2 October 2020
The first stage of the malware in the app is a downloader that does not contain any harmful code. This is why the app is not detected by Google. But later, the application updates itself into the Anubis malware.
In order to show how Anubis works, we collected several applications from the Play Store.
Using the internal reverse engineering tools of Orange Cyberdefense, we were able to decompile the application and study its java code.
The first stage of the application seems legitimate but requires some odd permissions like “Request_install_packages” (which is a yellow flag permission).
Figure 1: Application permissions recovered from the manifest
This permission is granted so that the application can download the update in the background…
Figure 2: Login to the C&C and download the update
…and updates itself with the received packet without asking the user permission.
Figure 3: Source code executed when receiving the update
Once the application is updated, it launches a new “Activity” (stage 2).
To recover the updated APK, we will use the Google emulator. Thanks to ADB (Android Debug Bridge), we can download it from the smartphone.
Figure 4: ADB commands to recover a file from the emulator
Once disassembled, the APK contains more than 50 classes and hundreds of functions. The code being obfuscated, a lot of classes/variables have the same name. This makes static analysis of the code quite long and painful.
So, we start by looking at the Android manifest to know what class is launched at the start of the application.
Figure 5: Manifest extract
We will realize later that this class does not exist yet. We therefore supposed that the application could create a second dex file (Dalvik Virtual Machine, compiled code of an APK) containing the missing classes and functions.
A dex file references any classes or methods used within an app, which means that we could not do a static analysis of an APK without it.
We searched for where and when the 2nd .dex file was created. The emulator provides the logs of all launched applications. The malicious application actually used this logging system and was not disabled by the creators of the malware.
Figure 6: Searching for the creation of the dex file in the emulator logs
Note that, indeed, a file is created in the directory “app_files”.
We tried to recover it via ADB, but the directory is missing from the phone. The application probably deleted this directory and its files.
To prevent the deletion, we searched for called deletion function in an execution trace. Then hook it, we will be able to recover the missing dex file.
To find the function, we used the strace command (Linux tool to track system calls) in an ADB shell on the zygote process (father of all other applications on Android). This created a complete execution trace of the running emulator. In a second terminal, we installed and launched the application.
In the logs the unlink function seems to be the one which delete our file.
Now, the hook prevents the malware from deleting this file. Several methods are possible, we used the Frida tool (https://github.com/frida).
Figure 7: Frida script that replaces the unlik call with a simple log
We could then download our second dex file via ADB directly on the smartphone.
Nota bene: If you use an emulator who runs an Android version older than 25, you will get an .odex and a .vdex file instead of a .dex file.
It’s possible to get the second dex file through static analysis. We can see that an encoded data file is in the APK and this might just be the dex file we are looking for. To find the decrypting function, we tried to grep “255” or “^” character in all the java classes. Three results seem to be very interesting and they all were in the same class.
Only one function has the corresponding characters (all unused codes were removed from this function):
Figure 8: Extract of the decompiled source code that contains the xor function
We can see the function is XORING two variables, moreover this looks like a RC4 crypto function (the pseudo-random generation algorithm to be precise).
So we are looking for the Key-scheduling algorithm in order to find the key (in absence of communication with the C&C, the key had to be hard-coded within the application).
In the same class, we found this function:
Figure 9: Source code of the generation of the permutation matrix
Which was called here:
Figure 10: Source code of initialization of the key
And here is the key. We serialize it in order to decode the dex file with a python script.
We just had to decode using the rc4.decrypt function and we will have our second dex file.
The 7 samples of Anubis (and 3 sample of another malware) have all the same packer architecture. We made a python script that gives the corresponding dex file of any input APK.
The extracting script unzips the APK file and decompiles it (transforms .class in .java thanks to jadx), then searched for the key.
The key have the following structure:
Figure 11: Example of initializing the key in the source code
The following regex will match all possible keys:
Figure 12: Python regex to find the key
Using the found key, the script tries to decode any data file found in the APK resource. The right decoded dex file will have a Zip header (‘PK’).
The stage 3 is the Anubis Malware. When it is launched, the “Accessibility menu” is opened and the user is asked to enable access for “Google Play Protect”. Of course, it is a trick and not the authentic “Google Play protect” screen. An user can be easily lure and will give the malware the last permissions it needs to trace all the users actions on the phone and read any window content.
At this stage, the code is also very obfuscated, but there is no dead code ; it is a bit more readable.
This is the last stage of the malware. Before finding what it does, we will have to discover how it communicates.
We tried to grep for any HTTP HTTPS and PHP expressions in the java class and we found this:
First, we thought that this was how the malware gets its order. But after some digging into the code, this is in fact how the malware gets the C&C address.
The C&C address is encoded in Base64, so we have to find how to read it. Here it is the decode function which uses a custom function and the Base64.decode function.
The server name is stored in the shared preferences folder (that is used to keep a variable in memory even if the user closes the application). The variables are stored encoded, we will have to search for the decoding fonction.
We scripted both these functions in python:
In the first exchange with the C&C, the malware will send the list of installed packages, so that the C&C will know if they are any interesting application installed on the device (e.g. banking applications) or to prepare a more complex social engineering plan.
The malware can start at boot because of the authorizations we gave it (android.permission RECEIVE_BOOT_COMPLETED) without any user’s action.
Moreover, we cannot delete the application. Upon trying it displays a message saying “System apps cannot be deleted”.
We cannot re enable Google Play Protect either…
…or reset the system.
All of this is possible because the malware can track the user actions. If it detects that we try one of the three actions above, it will launch a new activity that displays an Alert-dialog in the Homescreen before you can change anything.
In SDK version > 23, Android would kill applications that run for too long in the background for battery optimization. The malware bypasses this by making an exception for the malicious application.
The malware searches for some specific application/package (they are more than 100 app names, mostly banking apps or crypto wallets).
If one of them exists, the malware will wait for it to start. The malware then displays a corresponding page that will trick the user into giving his credentials.
The corresponding page is sent by the C&C server and the malware can get all applications that are currently running on the smartphone. This, thanks to the PACKAGE_USAGE_STATS permissions we gave it.
On the left, the real EBay application sign in menu. On the right, the fake one.
The keylogger tracks three different events: “Clicked”, “Focused” and “Text”. This works in every app.
TYPE_VIEW_CLICKED (eventType=1)
Represents the event of clicking on a View like Button, CompoundButton, etc.
8: TYPE_VIEW_FOCUSED (eventType=8)
Represents the event of setting input focus of a View.
16: TYPE_VIEW_TEXT_CHANGED (eventType=16)
Represents the event of changing the text of an EditText.
The keylogger is disabled by default, but can be enabled by a command sent from the C&C server.
The malware can also find a specific file (or just use an entire directory), encrypt it with the RC4 algorithm, and send it to the C&C.
As you can see, the malware browses all the different memory storage.
Thanks to the keylogger, the malware can already read sms, but the malware also requests to be the default SMS app or make SMS/call forwarding.
The malware can get all the contacts from the Android phone book with the CONTENT_URI field.
After getting the phone book, the malware can send sms messages to all the contacts or to a specific one.
The message body is received from the C&C.
In order to avoid strange or security number, the malware sends a text message only to numbers that respect this condition:
This concludes this analysis of the banking malware Anubis. Orange Cyberdefense were able to identify the different stages of infection, and automate the recovery of the final charge. The examination of this payload allowed us to contact the C&C and recover its different functionalities. All of this will allow us to inform our partners about this family’s threats, to help them protect themselves and their customers.