1/7 @cryptax June 20, 2022 Tracking Android/Joker payloads with Medusa, static analysis (and patience) cryptax.medium.com/tracking-android-joker-payloads-with-medusa-static-analysis-and-patience-672348b81ac2 @cryptax Jun 20 · 4 min read I am looking into a new sample of Android/Joker, reported on June 19, 2022 by @ReBensk: afeb6efad25ed7bf1bc183c19ab5b59ccf799d46e620a5d1257d32669bedff6f Android/Joker is known for using many payloads: a first payload loads another payload, which loads another one etc. Matryoshka dolls-style 😁. See an analysis of a previous Joker sample. This sample uses many payloads too, but the implementation to load the payloads is a bit different. I’ll detail. Medusa I recently discovered Medusa and like it very much… for dynamic analysis (I still prefer static analysis, everybody knows that by now?). Medusa is easy to use and comes with a collection of ready-to-use hooks. Launch an Android emulator, a Frida server, install the sample, then launch Medusa python3 medusa.py . Select the hooks you want to use (search through hooks with the search command, then use to use a given hook, finally compile the list of hooks). Those are the hooks you need (I recently contributed to the last two hooks): use http_communications/uri_loggeruse encryption/cipher_1use code_loading/dump_dyndexuse code_loading/load_class Finally, start the malware ( run -f package_name , or run -n 0 if you have a single sample installed on your emulator). https://cryptax.medium.com/tracking-android-joker-payloads-with-medusa-static-analysis-and-patience-672348b81ac2 https://cryptax.medium.com/?source=post_page-----672348b81ac2-------------------------------- https://cryptax.medium.com/?source=post_page-----672348b81ac2-------------------------------- https://twitter.com/ReBensk/status/1538513506999250945?s=20&t=cmnuXQQGDc6ovcRJQjvz_A https://cryptax.medium.com/live-reverse-engineering-of-a-trojanized-medical-app-android-joker-632d114073c1 https://github.com/Ch0pin/medusa https://github.com/Ch0pin/medusa/pull/18 2/7 I use URI hooks (http_communications/uri_logger) in Medusa and see the malware calls those URLs. Android/Joker is known to use URLs such as xxx[.]aliyuncs.com. As Android/Joker samples usually don’t make things simple for malware analysts, I somewhat expected those URLs to be encrypted. Medusa has decryption hooks too. Bingo! The look4.oss-ap[..]aliyuncs.com URL is encrypted. The decryption hooks, encryption/cipher_1, with shows the decrypted value. My dynamic DEX dumper + the convenient loadClass hooks show several files are dynamically loaded: DexClassLoader called: /data/user/0/com.designemoji.keyboard/files/audience_network.dex[+] Dumped /data/user/0/com.designemoji.keyboard/files/audience_network.dex to dump_1loadClass: com.designemoji.keyboard.EnableActivityloadClass: com.facebook.ads.internal.dynamicloading.DynamicLoaderImpl...PathClassLoader(f,p) called: /data/user/0/com.designemoji.keyboard/cache/nuff[+] Dumped /data/user/0/com.designemoji.keyboard/cache/nuff to dump_2loadClass: seek...DexClassLoader called: /data/user/0/com.designemoji.keyboard/files/seek[+] Dumped /data/user/0/com.designemoji.keyboard/files/seek to dump_3DexClassLoader called: /data/user/0/com.designemoji.keyboard/files/Yang[+] Dumped /data/user/0/com.designemoji.keyboard/files/Yang to dump_4loadClass: com.xjuysloadClass: com.android.installreferrer.api.InstallReferrerClient 3/7 The first DEX ( audience_network.dex ) belongs to Facebook. I am not after this. The 3 other DEXes ( nuff , seek and Yang ) are far more promising. Note they are loaded by PathClassLoader for nuff , and DexClassLoader for the other 2. Loading nuff (payload 1) DroidLysis doesn’t detect any use of DexClassloader , PathClassLoader or InMemoryDexClassLoader . So, how is the first payload loaded? Let’s locate the URL (look4[…]aliyuncs.com). It is encrypted, so I search where encrypted is used in DroidLysis’ detailed report. ## Cipher- file=./emojikeyboard.apk- afeb6efad25ed7bf1bc183c19ab5b59ccf799d46e620a5d1257d32669bedff6f/smali/f/a/a/a.smali no= 25 line=b'.method private b()Ljavax/crypto/Cipher;\n'- file=./emojikeyboard.apk- afeb6efad25ed7bf1bc183c19ab5b59ccf799d46e620a5d1257d32669bedff6f/smali/f/a/a/a.smali no= 63 line=b' invoke-static {v0, v1}, Ljavax/crypto/Cipher;- >getInstance(Ljava/lang/String;Ljava/lang/String;)Ljavax/crypto/Cipher;\n' Fortunately, there are not many different locations, and I directly head to the good one: f.a.a.a . Encrypted strings are decrypted using PBEWithMD5AndDES . I write a static decryptor. Decrypted=Decrypted=getClassLoaderDecrypted=loadClassDecrypted=seekDecrypted=melody The URL gets a JAR, stores it in a cache directory of the application, and then loads it via … getClassLoader ! That’s why DroidLysis didn’t see it! (to be fixed). Code loading the JAR with getClassLoader, then invokes a method named melody() Static analysis of nuff (payload 1) The JAR contains a classes.dex with a single class named seek , and a method named melody. It is simple to understand: 1. It downloads DEX file from https://github.com/cryptax/droidlysis https://github.com/cryptax/misc-code/blob/master/JokerDecryptPBE.java 4/7 2. It stores that DEX in the application’s file directory, with filename seek 3. It loads the DEX using DexClassLoader 4. It invokes cantus.bustle() in that DEX Code of payload 1. Download URL for payload 2 — we also see that class cantus, method bustle is called. Static analysis of payload 2 Just guess what cantus.bustle() does? It downloads yet another DEX from https://xjuys.oss- accelerate[.]aliyuncs.com/xjuys ! Payload 2 is loading … Payload 3 This time, the payload will be stored in a file named Yang , and it will search for class com.xjuys and method xjuys . Static analysis of payload 3 5/7 This com.xjuys JAR had been already used in several other samples of Joker (sha256: 2edaf2a2d8fd09a254ea41afa4d32b145dcec1ab431a127b2462b5ea58e2903d ). It loads dynamically 2 other ZIPs: 1. 1. We have already seen this payload. It is the same as and contains facebook hooks. 2. . It stores the file in the app’s file directory, with filename KBNViao . Then, it loads com.appsflyer.AppsFlyerLib and methods init() then startTracking() [love the name of the method, don’t we? 😏]. This is , a mobile analytics library. Connect to remote URL and download payload 4. Summary The initial DEX is quite heavily obfuscated Payload 1 ( designmoji / nuff ) has no other use than loading Payload 2 Payload 2 ( nunber / seek ) enables notification listeners (we haven’t detailed this in this article) and loads Payload 3 Payload 3 ( xjuys / Yang ) has yet more malicious code (not detailed here) and loads 2 additional DEX: one for Facebook, the other one contains Apps Flyer SDK. Payload 4a and 4b: Facebook hooks + Apps Flyer SDK. 6/7 APK getClassLoader() Payload 1 Download from https://look4[.]oss-ap-southeast-5[.]aliyuncs.com /designemoji Filename on smartphone: appdir/cache/nuff Call: seek.melody() Payload 2 Download from https://look4[.]oss-ap-southeast-5[.|aliyuncs.com /nunber DexClassLoader Filename on smartphone: appdir/files/seek Call: cantus.bustle() Payload 3 Download from https://xjuys.oss-accelerate[.Jaliyuncs.com/xjuys DexClassLoader Filename on smartphone: appdir/files/Yang Call: com.xjuys.xjuys() DexClassLoader Payload 4b Download from https://beside[.Joss-eu-west-1 Payload 4a Download from https://xjuys[.]oss-accelerate [.Jaliyuncs.com/fbhx1 [.Jaliyuncs.com/af2 Facebook hooks Mobile Analytics SDK 6/7 7/7 — Cryptax