FortiGuard Labs Threat Research
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.
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().
Figure 4. The function b.a((Context)this)
Figure 5. The function oC()
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
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.
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.
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.
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.
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.
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.
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.
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.
Figure 26. The two ways to generate busybox
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
Figure 29. The shell script to be executed after successful root
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.
Figure 31. The function this.c(Context arg7)
Figure 32. Deletes files in the folder files/.snow/.zip/
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.
Activity |
Package |
com.facebook.application.MainActivity |
com.facebook.application |
com.music.cloud.app.player.MainActivity |
com.music.cloud.app.player |
com.x.a.b.a.Aty |
com.para.android.power |
com.android.shopping.paye.MainActivity |
com.android.shopping.paye |
com.fly.me.ssp.be.WakeActivity |
com.fly.me.ssp.be |
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.