Anatomy of an Android Malware Dropper

0

Recently at EFF’s Threat Lab, we’ve been focusing a lot on the Android malware ecosystem and we’ve provided tools for his analysis. We noticed many examples of Android malware in the tor-hydra family surfaced, posing as banking apps to trick unsuspecting customers into installing them. In this article, we will take an example of such a sample and analyze it using open source tools available to everyone.

In short

the to taste we will be reviewing was first seen on March 1, 2022. This particular malware poses as the banking app for BAWAG, a leading financial institution in Austria. On first run, the app prompts the user to give the app “accessibility services” permission. The Accessibility Services permission grants an app broad access to read the screen and mimic user interaction. When granting permission, the app backgrounds itself. Any attempt by the user to uninstall the app is prevented by the app interrupting and closing the uninstall dialogs. Trying to open the app again also fails – nothing happens.

Android Package APK Analysis

AndroidManifest.xml

the Android app manifesto the file contains a list of permissions, Activitiesand the services provided by an application. If an activity is not listed in the application manifest, the application cannot launch that activity. Using an Android static analysis tool like jadx Where apktool we can take a look at the XML manifest. The malicious app’s manifest asks for a wide range of permissions, including the ability to read and send SMS messages (a common way for malware to spread), request installation and removal of packages, read contacts, initiate calls, and request the aforementioned accessibility service. . Additionally, a number of classes are referenced that are not defined anywhere in our jadx– reverse code:

  • com.ombththz.ufqsuqx.bot.components.commands.NLService
  • com.ombththz.ufqsuqx.bot.components.injects.system.InjAccessibilityService
  • com.ombththz.ufqsuqx.bot.components.locker.LockerActivity
  • com.ombththz.ufqsuqx.bot.components.locker.LockerActivity$DummyActivity
  • com.ombththz.ufqsuqx.bot.components.screencast.ScreencastService
  • com.ombththz.ufqsuqx.bot.components.screencast.ScreencastStartActivity
  • com.ombththz.ufqsuqx.bot.components.screencast.UnlockActivity
  • com.ombththz.ufqsuqx.bot.components.socks5.Socks5ProxyService
  • com.ombththz.ufqsuqx.bot.HelperAdmin$MyHomeReceiver
  • com.ombththz.ufqsuqx.bot.PermissionsActivity
  • com.ombththz.ufqsuqx.bot.receivers.MainReceiver
  • com.ombththz.ufqsuqx.bot.sms.ComposeSmsActivity
  • com.ombththz.ufqsuqx.bot.sms.HeadlessSmsSendService
  • com.ombththz.ufqsuqx.bot.sms.MmsReceiver
  • com.ombththz.ufqsuqx.bot.sms.SmsReceiver
  • com.ombththz.ufqsuqx.core.injects_core.Screen
  • com.ombththz.ufqsuqx.core.injects_core.Worker
  • com.ombththz.ufqsuqx.core.PeriodicJobReceiver
  • com.ombththz.ufqsuqx.core.PeriodicJobService
  • com.ombththz.ufqsuqx.MainActivity
  • info.pluggabletransports.dispatch.service.DispatchReceiver
  • info.pluggabletransports.dispatch.service.DispatchService
  • info.pluggabletransports.dispatch.service.DispatchVPN
  • org.torproject.android.service.OrbotService

The fact that the manifest references the activities, services and receivers it wants to run without defining them is the first indication that we are dealing with an “Android dropper”.

Unboxing Android Droppers

An Android dropper is malware that obfuscates its behavior by hiding its payload and decoding and loading only the code it needs at runtime. Like Ahmet Bilal Can Explainthis makes it more difficult for AV and security researchers to detect malware by including “reflection, obfuscation, code stream flattening, and garbage codes to do [the] stealth unboxing process. Although stealthy, the steps the malware takes to hide can still be detected and circumvented with a little help from the dynamic instrumentation toolkit. Frida. Frida is able to inject herself into the control flow of a running application, introducing her own code. This can be useful for detecting typical methods used by malware to disguise itself and load the underlying payload. In this case, we can use a short script to detect that Java classes are dynamically loaded:

var classLoader = Java.use('java.lang.ClassLoader');
var loadClass = classLoader.loadClass.overload('java.lang.String', 'boolean');

loadClass.implementation = function(str, bool){
  console.log("== Detected ClassLoader usage ==");
  console.log("Args: ", str, bool);
  return this.loadClass(str, bool)
}

Running this code, we get

$ frida -U -f com.ombththz.ufqsuqx -l class-loader-usage.js --no-pause
     ____
    / _  |   Frida 15.1.16 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
Spawned `com.ombththz.ufqsuqx`. Resuming main thread!                   
[Android Emulator 5554::com.ombththz.ufqsuqx]-> == Detected ClassLoader usage ==
Args:  com.honey.miletes.k false
== Detected ClassLoader usage ==
Args:  android.support.v4.content.FileProvider false
== Detected ClassLoader usage ==
Args:  com.ombththz.ufqsuqx.App false
== Detected ClassLoader usage ==
Args:  com.ombththz.ufqsuqx.MainActivity false
== Detected ClassLoader usage ==
Args:  com.ombththz.ufqsuqx.core.injects_core.Worker false
== Detected ClassLoader usage ==
Args:  com.ombththz.ufqsuqx.bot.PermissionsActivity false
== Detected ClassLoader usage ==
Args:  org.torproject.android.service.OrbotService false

Our missing classes are indeed dynamically loaded!

Previous iterations of tor-hydra malware dynamically loaded a dex file (an Android Dalvik executable file), which can be seen with adb logcatand used the system call unlink to delete this file, which would be seen in a strace call. For this application we can use the command

monkey -p com.ombththz.ufqsuqx -c android.intent.category.LAUNCHER 1 && set `ps -A | grep com.ombththz.ufqsuqx` && strace -p $2

to see system calls in real time. We did not observe unlink being used in this sample, so this iteration was doing something different. Java provides a method in java.io.File called deletewhich will not trigger the unlink system call. Using this script, we can detect when this method is used, alert us to the file it attempted to delete, and make it a non-operation:

var file = Java.use("java.io.File")

file.delete.implementation = function(a){ 
  console.log("=> Detected and bypassed Java file deletion: ", this.getAbsolutePath());
  return true;
}  

The first deleted files are interesting:

=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/tyfkjfUjju/HjIgfhjyqutIhjf/tmp-base.apk.gjGyTF88583765359401054429.88g
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/tyfkjfUjju/HjIgfhjyqutIhjf/dfGgIgyj.HTgj
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/tyfkjfUjju/HjIgfhjyqutIhjf/base.apk.gjGyTF81.88g
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/tyfkjfUjju/HjIgfhjyqutIhjf
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/shared_prefs/multidex.version.xml.bak
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/shared_prefs/pref_name_setting.xml.bak
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/files
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/shared_prefs/prefs30.xml.bak
=> Detected and bypassed Java file deletion:  /data/user/0/com.ombththz.ufqsuqx/files/all_tor.zip

Once we issue a adb pull to download the base.apk.gjGyTF81.88g device file we can use jadx again to determine that this includes missing class definitions referenced in the manifest.

Examining the decompressed payload

Looking at these files, there is a string obfuscation method that appears thousands of times in code, unchanged from instance to instance:

private static String $(int i, int i2, int i3) {
    char[] cArr = new char[i2 - i];
    for (int i4 = 0; i4 < i2 - i; i4++) {
        cArr[i4] = (char) ($[i + i4] ^ i3);
    }
    return new String(cArr);
}

Wherever we see a call that sounds like $(166, 217, 28670) in the code it refers to this function and uses the $ variable in the same scope to return a string. We can use a Java sandbox like this one to set the local scope $ variable, the $ method and print the decoded string.

In sources/com/ombththz/ufqsuqx/bot/network/TorConnectionHelper.java we see a method that looks like a promising lead called loadAdminUrl. Decode the $(556, 664, 4277) call, we get a base64-encoded onion address:

http://loa5ta2rso7xahp7lubajje6txt366hr3ovjgthzmdy7gav23xdqwnid.onion/api/mirrors

This address is available on the Tor network and contains a base64-encoded URL that points to the command and control (C&C) server, the server from which the malware operator issues commands. The author of this message contacted the Tor project on March 7 to inform them of this C&C server. When the application starts, the Tor network is connected by a code extracted from Orbot in order to discover the C&C server, then the Tor connection is quickly dropped. During this first survey, the referenced domain yuuzzlllaa.xyzbut that has since changed to zhgggga.in. We can see a login page for the C&C server administrator when accessing:

C&C Login Page

One of the main features of the Tor network is censorship resistance. If you can access the Tor network, you can access information and websites that cannot be easily removed due to the way the network is architected. This is a good thing for dissidents in censorship regimes or whistleblowers trying to obtain inside information for journalists: the services they rely on will be available even if their adversaries do not want them. It is, however, a two-sided coin – in this case, the malware is also capable of directing victims’ devices to C&C servers in a way that cannot be removed. There is no way to have one without the other and keep the integrity of the network intact. In this case, the clearnet domain yuuzzlllaa.xyz was probably deleted after being reported, then the malware operator created another domain to zhgggga.in without much disruption to malware command and control. In these cases, reporting malicious C&C domains is like a mole game: as soon as you remove one, the next one pops up.

In the file com/ombththz/ufqsuqx/bot/DexTools.java we see an interesting method, run()which loads a level 2 payload from the C&C admin URL path /payload. It’s a dex file which can be decoded by jadx to an app ID of com.fbdevs.payload. Unfortunately, for the purposes of our analysis, this file contains mostly uninteresting, non-malicious code.

Looking at the om/ombththz/ufqsuqx/bot/components/ way, many components seem to be inherited directly from Android BianLian malware, an excellent analysis of which can be found here. One of the components not included in this previous iteration is under the socks5 path, which opens a proxy server on a specified host to receive commands and launch attacks. All components are activated and controlled by the C&C server via a Firebase Cloud Messaging (FCM) connection, allowing messages targeting specific devices.

Fight against malware

Despite relatively state-of-the-art techniques employed to thwart the analysis, a few powerful publicly available open source tools were used to interrupt the flow of control and reverse engineer this sample. More complex malware will detect hardware profiles and can determine if they are running in an emulator, and modify their behavior to further obscure their core functionality. Still others will deploy malicious code into deeper payloads in an attempt to further bury its true behavior. However, this example shows how a few simple steps can be taken to peel back those layers to eventually uncover the control flow of a new class of malware. In the future, other samples of this class may be similarly analyzed to track changes in the ecosystem and how malware developers respond to attempts to mitigate their effectiveness.

Analyzing malware and tracking its progress is important in combating it. Not only does this translate into better signatures for antivirus software to use and protect users from, but it helps us understand what protections are needed at the operating system level and guides platform security recommendations. Sometimes this can result in C&C servers being shut down and botnet targets getting a much-needed reprieve. And finally, it gives users insight into the software running on their devices so they can regain control.

Share.

Comments are closed.