Unmasking Android Malware: A Deep Dive into a New Rootnik Variant, Part II
Credit to Author: Kai Lu| Date: Sun, 09 Jul 2017 14:00:00 +0000
In part I of this blog, I finished the analysis of the native layer of a newly discovered Rootnik malware variant, and got the decrypted real DEX file. Here in part II, we will continue our analysis.
A look into the decrypted real DEX file
The entry of the decrypted DEX file is the class demo.outerappshell.OuterShellApp. The definition of the class OuterShellApp is shown below.
Figure 1. The class demo.outerappshell.OuterShellApp
We will first analyze the function attachBaseContext(). The following is the function aBC() in the class LinkInnerShell.
Figure 2. The function aBC() in the class LinkInnerShell
The program uses DexClassLoader to dynamically load a DEX file and execute the function load() in the class demo.innerappshell.LoadTargetApp. The function moveSourceApk() is used to decrypt the file hello.apk in folder assets, and then write the decrypted data into the hello.apk in the folder /data/data/net.gotsun.android.wifi_configuration/files/.
Figure 3. The function moveSourceApk
Next, we analyzed the function onCreate().
- b.a(((Context)this)): Starts the service com.dhy.kqib.c.c.
Figure 4. The function b.a((Context)this)
- this.mLinkInnerShell.oC(): Invokes the function initCreate in the class demo.innerappshell.LoadTargetApp.
Figure 5. The function oC()
Analysis of hello.apk
The following is the decompiled structure of the decrypted hello.apk.
Figure 6. The decompiled structure of the decrypted hello.apk
We will continue to analyze the function load and initCreate in the class demo.innerappshell.LoadTargetApp.
In the function load(), it decrypts the file source.apk in the folder assets and writes the decrypted data into source.apk in folder /data/data/net.gotsun.android.wifi_configuration/files/ It then replaces system DexClassLoader.
The following is the function initCreate.
Figure 7. The function initCreate
The function replaceSystemApplication() is used to execute the function onCreate() in the class com.demo.MyApplication. The class should be inside source.apk.
Figure 8. The function replaceSystemApplication
Analysis of source.apk
Let’s next look into the decrypted source.apk. The following is the decompiled structure of the decrypted source.apk.
Figure 9. The decompiled structure of the decrypted source.apk.
For now, we can see that the implementation of the original legal app is inside the decompiled structure of source.apk. Obviously, the malware developer added the malicious codes into the original legal app and repackaged it.
Next, we will look into the function onCreate() in the class com.demo.MyApplication.
Figure 10. The function onCreate() in the class com.demo.MyApplication
It finally invokes the following function through tracing.
Figure 11. The function start
This function first checks to see if the file libhjdSsDMxuUQaCVMDbootstrap.so exists in the folder files. If not, then the program could copy all files in folder assets/awsrabf/ into the folder files/awsrabf/. The file list in the folder assets/awsrabf/ is shown below.
Figure 12. The file list in the folder assets/awsrabf/
Next, it reads the file /data/app-lib/net.gotsun.android.wifi_configuration-1/libhjdSsDMxuUQaCVMDbootstrap.so and decrypts it, as well as writes the decrypted data into the file /data/data/net.gotsun.android.wifi_configuration/files/libhjdSsDMxuUQaCVMDbootstrap.so. Finally, it loads the .so library libhjdSsDMxuUQaCVMDbootstrap.so into the folder /data/data/net.gotsun.android.wifi_configuration/files/. When it loads the .so file, the function JNI_Onload can then be invoked.
Next, we continue to analyze what the function JNI_Onload in libhjdSsDMxuUQaCVMDbootstrap.so does.
In the function JNI_Onload, it can decrypt the data of libLDyARNDidKiYcqzxdynamicloader.so in the folder /data/data/net.gotsun.android.wifi_configuration/files/awsrabf/ and write the decrypted data into the file /data/data/net.gotsun.android.wifi_configuration/files/LDyARNDidKiYcqzxdynamicloader.jar. It then uses DexClassLoader to dynamically load this .jar file. Next, it invokes the function start in the class com.nativedroid.module.dynamicloader.Dynamic.
Figure 13. Invokes the function start in the class com.nativedroid.module.dynamicloader.Dynamic
The following is the definition of the function start in the class com.nativedroid.module.dynamicloader.Dynamic.
Figure 14. The function start in the class Dynamic
Figure 15. The function start in the class SDK
This function first decrypts libQSRDZTuWgdcfLbEXdaemon.so in the folder lib/armeabi and writes the decrypted data into the file QSRDZTuWgdcfLbEXdaemon.so in the folder /data/data/net.gotsun.android.wifi_configuration/files/. It also decrypts three JARs (bcVPHHDpaVhsxLGUlala.jar, qBikvXzxORCegosEzxc.jar,UniUxqsTCxkMnvngbt.jar) in the same folder. It then injects the three JARs into the DEX path list. Finally, it invokes the function start in the class com.nativeroid.sa.sdk.SDK. Through investigation, its main purpose is Ads promotion and push.
Analysis of the main activity WifiConfigurationActivity
In AndroidManifest.xml we learn that the main activity of the malware app is net.gotsun.android.wifi_configuration.WifiConfigurationActivity. Next, we will examine the function onCreate().
The following is a comparison between the malicious app’s onCreate() and the original app’s onCreate(). This comparison allows us to see that the malicious app has added some codes.
Figure 16. The comparison of the function onCreate()
The malware’s developer repackaged the original app and added some malicious codes.
Let’s examine these newly added codes.
- f.a(): Start the service com.android.j1collection.GoogSer.
Figure 17. The function f.a()
Next, we see what the service GoogSer does.
Figure 18. The execution flow of the service GoogSer
The following is the definition of the function com.android.jar1ah.a.b(Context arg6).
Figure 19. The function com.android.jar1ah.a.b(Context arg6)
Following is an explanation of what some key functions do.
- a.c(arg6):
It first requests a URL hxxp://gp.miaoxia123.com/cr/sv/getGoFile?name=onlyV17041401Aj1arso32 and gets the json format response.
Second, it continues to request the URL hxxp://sh.pencilli.com/cr/sdk/dynV17041701D/des_onlydyV17041701Dj1so32.zip and writes the data of response into the file /data/data/net.gotsun.android.wifi_configuration/files/23hammerhead32/net.gotsun.android.wifi_configuration12hammerhead2.
It then decrypts the file net.gotsun.android.wifi_configuration12hammerhead2 and decompresses the decrypted zip file that includes the file onlydyV17041701Dj1so32. It then copies this file into the file /data/data/net.gotsun.android.wifi_configuration/files/1497912689813_onlydyV17041701Dj1so32.so. The string “1497912689813” is a time stamp.
- k.a(arg6, k.a(f.class)): f.class has 3 native methods: k.a(f.class) gets the string array including the three methods description. k.a(arg6, k.a(f.class)) stores the content into file /data/data/net.gotsun.android.wifi_configuration/files/na1l2t/ntmp1101411060. And finally, the string “1101411060” is calculated by joining pid and tid.
- System.load(v3_1): Loads /data/data/net.gotsun.android.wifi_configuration/files/1497912689813_onlydyV17041701Dj1so32.so.
In the function f.a(this.a.getApplicationContext()), it can invoke the native method void a(Context arg0) of the class com.android.jar1ah.f.
The function this.a.a() starts the thread com.android.j1collection.b. The following is its definition.
Figure 20. The thread class com.android.j1collection.b
We found that it can launch the following process.
- i.init(this.getApplicationContext()): The function could start the service StaService. It can also send an SMS message to the subscription number.
- bi.In(this.getApplicationContext()): In this function, it requests the URL hxxp://down.smykttum.com/thinking/group/rtt_0511_669.apk and loads the dex file dynamically. It then invokes the method initRoot of the class cn.engine.RootPermApi. The method initRoot is used to execute rooting the device.
- XCZihjgerghuCSer.class: Makes the app Ads promotion and installs app on the device.
- ASjoifewnffffhuwefBSer: Sends the SMS message to a specific number and then deletes it in the SMS box.
Next, we will run a deep analysis of the function bi.In(Context arg5). The definition of the function bi.In(Context arg5) is shown below.
Figure 21. The function bi.In(Context arg5)
This function performs the following main work.
- Reads data from web.ini in the folder assets in package, and parses it to set the variables bi.appChannel and bi.md5Channel.
- Sends an http post request to the URL hxxp://t.eqqsl.com/ggview/rsddateindex. It then decodes the response data and decrypts it to get a json format data. The following is the traffic captured.
Figure 22. The captured traffic that requests the URL hxxp://t.eqqsl.com/ggview/rsddateindex
The JSON format data we get is shown below.
Next, parse the JSON format data to get the URL of downloading root exploit payload. The URL is hxxp://down.smykttum.com/thinking/group/rtt_0511_669.apk. The backup URL of downloading root exploit payload is hxxp://down.zigyfdeb.com/backokr/rtt_0310_577.apk that is hard-coded in the program. Additionally, we also found an update root exploit APK file as shown below.
The left analysis is based on the rtt_0511_669.apk.
- It then sends an http request to the URL hxxp://down.smykttum.com/thinking/group/rtt_0511_669.apk to download the root exploit payload, and save it as the file /data/data/net.gotsun.android.wifi_configuration/files/.default/.p.apk.
- It loads the DEX file dynamically with DexClassLoader, and executse the function initRoot(Context arg0, String arg1, String arg2) of the class cn.engine.RootPermApi. This function is used to execute a root exploit to root android device. After the rooting is successful, the malware could install some malicious apps in the folder /system/pri-app/ and do other malicious activities.
Figure 23. The function initDexFunction
Next, we will look into the file rtt_0511_669.apk. It’sin a jar file format and includes classes.dex. The following is the decompiled structure of rtt_0511_669.apk.
Figure 24. The decompiled structure of rtt_0511_669.apk
The following is the definition of the function initRoot(Context arg9, String arg10, String arg11) in the class cn.engine. RootPermApi.
Figure 25. The function initRoot in the class cn.engine. RootPermApi
The following is an explanation of some of the key functions.
- Checks to see if the package "com.fly.me.ssp.be" has been installed.
- Generates the file /data/data/net.gotsun.android.wifi_configuration/files/.snow/busybox. The following is the code for how to generate the file busybox tool. It uses two ways to generate it. One is through downloading it from a hard-coded URL. The other is through decrypting the hard-coded data to generate it. The other files in the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow/ are generated in the same way.
Figure 26. The two ways to generate busybox
- If SDK version is larger than 15, it generates the file /data/data/net.gotsun.android.wifi_configuration/files/.snow/supolicy.
- Generates the file /data/data/net.gotsun.android.wifi_configuration/files/.snow/.uok.
- Generates the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow/.zip/, and sets its mode with the command “chmod 777 .zip”.
- Starts a thread to do core work of rooting device.
Next, we look into the created thread. The following is the function run() of the newly created thread.
Figure 27. The function run() of the newly created thread
The following is the key code snippet found in the function b(c arg5, Context arg6, String arg7, String arg8) of the class cn.engine. RootPermApi.
Figure 28. The key code snippet of function b
- Generates the files .client and .service in the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow/.
- Generates the file .uks in the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow/.
- Generates some APK files to be installed, some ELF files, as well as a shell script to be executed after successful rooting.
Figure 29. The shell script to be executed after successful root
- com.wksnkys7.rtmst.b.ai.a(Context arg9): Executes root exploits.
Next, we continue to analyze the function a(Context arg9) in the class com.wksnkys7.rtmst.b.ai.a.
Figure 30. The function a(Context arg9) in the class com.wksnkys7.rtmst.b.ai.a
In this function, it does the following work.
- Checks to see if the file b.png exists in the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow/. If not, it can generate it. The file b.png is in a zip file format.
- Unzips the file b.png and writes the files r1, r2, r3, r4 into the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow/.zip/. It then sets their file mode with the command “chmod 777”.
- this.c(arg9): Executes the root exploits by starting a new thread. If it’s successful, the shell script rsh in the folder /data/data/net.gotsun.android.wifi_configuration/files/.snow./.zip/ can be executed, and the return value is true. There are four root exploits: r1, r2, r3, r4. After investigating these executable files, I found that r3 is the MTK root scheme from the dashi root tool. The exploits method in r4 comes from one exploit (CVE-2013-6282) of the open source project android-rooting-tools, and the exploit method in r2 is the CVE-2012-6422, which is a root exploit on Samsung Exynos. Additionally, comparing these results with the blog in January of 2017, I learned that both of them use the same root exploits. The shell scripts rsh is shown in Figure 29.
Figure 31. The function this.c(Context arg7)
- this.a(v0): Deletes some files in the folder files/.snow/.zip/.
Figure 32. Deletes files in the folder files/.snow/.zip/
- this.b.a(v0, this.c.ordinal()): Invokes the function a(boolean arg11, int arg12) in the class cn.engine. The following is its definition.
Figure 33. The function a(boolean arg11, int arg12) in the class cn.engine.f
In this function, it executes the command “/system/xbin/.cp add md5(packagename+'fuck')n". Then it starts the following activities in some apps installed.
Table 1. The activities to be launched in some installed apps (1)
Next, it checks to see if the two files .ci.pm and .cp exist in the folder /system/xbin/. If yes, it can start the following activities in some apps installed.
Activity | Package |
org.demo.in.DemoActivity | com.android.fk.json.tool |
org.app.info.grate.WakeActivity | org.app.info.grate |
om.android.upon.hash.Asaman | com.android.upon.hash |
com.setting.dysdtool.MainActivity | com.setting.dysdtool |
com.up.MActivity | com.android.tools.receiver |
Table 2. The activities to be launched in some installed apps (2)
At this point, we have finished our analysis of the root exploit payload rtt_0511_669.apk. In final part of the blog, Part III, we will take a deep look into the script shell rsh.