View Andromeda botnet
Original article:Http://blog.fortinet.com/post/A-Good-Look-at-the-Andromeda-Botnet
Translation:Xu Wenbo
Andromeda is a modular bot. The original bot contains only one loader. During its operation, it downloads related modules and updates from the C & C server. It also has the anti-Virtual Machine and anti-debugging functions. It injects itself into a trusted process and then deletes the original bots. The bot lurks for a long time (from a few days to a few months) to communicate with the C & C server. Therefore, it is difficult to obtain network traffic information between infected hosts and C & C servers.
The latest official version is 2.06, which contains new content in the packages sent by the bot. In addition, it can also distribute other diverse zombie variants, download related modules and updates.
Figure 1: Distribution of Andromeda displayed on the GeoIP Map
I. Package Logging
The package has a lot of redundant code, so you can hide the real code. It will call the GetModuleHandlerA API to obtain the bot base address, check the MZ mark and PE pattern, and then confirm whether there are 6 segments. If yes, the system loads data from the first segment for decryption, verifies the decrypted MZ mark and PE pattern, and calls the CreateProcessW API to re-load and execute the original bot, however, the dwCreationFlags value is set to create_suincluded. The packer injects the code in the decrypted 4th segments into the second process. Later, the package will use the same method to load another PE from the first segment.
This powerful package can embed and execute two different malicious codes at the same time. However, the data in the 4th segment is not in the PE format after decryption. Therefore, the package can only be carried and cannot execute Andromeda bot.
Ii. Loader
The loader first obtains the base address of ntdll. dll from the TEB structure and uses it as a parameter to obtain the API exported by ntdll, which improves the analysis complexity. API processing uses a checksum instead of a function name. Below are some API checksum and their corresponding names:
5584B067h OpenMutexA
5F467D75h SetErrorMode
5E639D43h VirtualFree
0AAEB7C1Eh VirtualAlloc
9ED23A16h LoadLibraryA
94D07C92h CloseHandle
8C552DB6h Process32Next
0B4D1BAFAh Process32First
99D6DD7Ah createconlhelp32snapshot
41D27AF6h GetModuleHandleA
Next, the loader will call OpenMutexA API to check the "lol" mutex to determine whether to skip anti-Virtual Machine and anti-debugging processing.
If the mutex is not found, the bot will confirm whether it is executed in the virtual machine or the debugging environment:
1) traverse the current process list, convert each process name to lowercase, and calculate its checksum. Compared with the embedded checksum, it represents the virtual machine environment. (2)
Figure 2: Anti-Virtual Machine
2) then try to call GetModuleHandleA API to load sbiedll. dll to check whether it is a Sandboxie VM.
3) query the following registry key and obtain the disk name (see figure 3 ):
Key: HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ Disk \ Enum
Skip the first 8 bytes and check the next 4 bytes (figure 4)
Currently, the loader detects three VMS, as shown in figure 4.
Figure 3: query the registry and obtain the disk name
Figure 4: Skip 8 bytes and check the next 4 bytes
4) Call the rdtsc command twice to calculate the difference in return values. A value greater than h indicates that the value is in the debugging environment.
If the bot loader detects any exceptions, it will not exit as other botnets directly, but will continue to run a short piece of code called "passive code" (passive mode code.
Passive mode code
This field code changes itself into svchost.exe and adds itself to the following registry key:
Key:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunValueName:SunJavaUpdateSchedData:%ALLUSERSPROFILE%\\svchost.exe
This code will open the local port 8000 for listening. When a remote command is received, cmd.exe is executed to receive and execute the command.
Iii. Main code injection
Call the SetEnvironmentVariableW API to save the full path of the initial bot to the environment variable src, and then call the ZwQueryInformationProcess API to check whether the system version is 32-bit or 64-bit. If it is running on a 32-bit system, the botnet will be injected with wuauclt.exe, and the negative will be injected with svchost.exe. (Our example is to run in a 32-bit system .)
BotNet creates wuauclt.exe, and its dwCreationFlags is set to create_suincluded. Call multiple MAP apiinjection into wuauclt.exe. Change the wuauclt.exe entry point code to the following code:
Push <address of injected code>
Retn
Finally, the bot calls ZwResumeThread apito activate the injection process wuauclt.exe and then exits directly.
4. initialize the local environment of the Main Code
All information of the injected code is obvious. There are no encrypted strings, code segments, and so on. The Bot calls the SetErrorMode API to disable most error warning windows. The parameter value is 0 × 8007, which indicates the following meaning:
The Bot calls the GetEnvironmentVariableW API and uses the environment variable src to obtain the full path of the initial bot. Then, it calls the SetEnvironmentVariableW API to set the variable as an empty string. The supervisor checks the Security ID of the current process (wuauclt.exe) to see if it belongs to the Administrator, and then sets the destination and registry key value for replication. Then, use the current clock tick value to determine the suffix of the file name.
The Bot may copy itself to one of the two destinations:
If the current user is an administrator, the "ar" flag is set to 1. The Bot sets the following registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run<%lu>%allusersprofile%\Local Settings\Temp\ms<%s>.<%s>
Otherwise, the "ar" flag is set to 0, and the registry is set as follows:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WindowsLoad%allusersprofile%\Local Settings\Temp\ms<%s>.<%s>
According to the current clock tick value, the file name suffix may be one of them: exe, com, scr, pif, cmd, or bat.
The Bot creates a mutex Based on the string generated by the system volume information. If the mutex already exists, the original bot sample is deleted and then exited directly. Otherwise, the bot copies itself to the destination and adds it to the registry so that it will run automatically the next time the system starts.
In the end, the bot will create two new threads to execute the previously saved modules and the DLL in the registry using the registry (figure 6 ). Of course, they use the RC4 encryption algorithm and have a fake ZIP header (figure 7 ).
Figure 6: create two threads to run the previously saved modules
Figure 7: these threads use RC4 encryption and have a fake ZIP Header
Now, the Local Initialization is complete, and the network operations with the C & C server will be prepared.
V. Network Operation Initialization
The Bot cyclically creates a thread every 23c000000h, that is, 6 days. Therefore, short-term monitoring of network traffic is not enough to detect the existence of Andromeda.
The format of the package sent for the first time is as follows:
Id: % lu | bid: % lu | bv: % lu | sv: % lu | pa: % lu | la: % lu | ar: % lu
The id value is generated based on the volume information of the local system.
The bid value is hard-coded and may be the compilation id.
The bv value is also hard-coded and may be the compiled version (currently 206 h (518 ))
The sv value indicates the system version of the affected machine.
The pa value is the return value of calling the ZwQueryInformationProcess API to determine whether the OS is 32-bit or 64-bit.
The la value is generated based on the IP address of www.update.microsoft.com.
The ar value is the return value of calling the CheckTokenMembership API. Check whether the bot runs under the Administrator permission.
The values of pa and ar are new data of this version of Andromeda.
Example 8. Figure 9 shows the same content after RC4 encryption, and Figure 10 shows the data after base64 encoding. Finally, Figure 11 shows the actual network traffic, and Figure 12 shows the binary representation of the received data packet.
Figure 8: Network Package example
Figure 9: After RC4 Encryption
Figure 10: base64 encoded string
Figure 11: real network traffic
Figure 12: Binary view of received data packets
The simple structure of the content is as follows:
12345 |
Struct RecvPack { INT CRC32; Char(*) Body; }*RecvPack; |
The C & C server does not use the same RC4 key to encrypt the response packet, but uses the id value. The length is only 4 bytes. Therefore, we cannot decrypt the response packet without sending data packets.
The received data packet, as shown in Figure 13 after decryption
Figure 13 received data packets decrypted
Its structure is as follows:
First, take a snapshot of the webpage control panel of the Andromeda C & C server to see the meaning of the command type ("Task type") (figure 14 ).
Figure 14: The webpage Control Panel snapshot of the Andromeda C & C server shows a variety of command types ("Task type ")
The received packet contains multiple contents (two in figure 13 ). In Figure 13, the Cmd type of the first block is 2, indicating "Install plug-in ". The Bot attempts to download the relevant modules, as shown in Figure 15.
Figure 15: Bot attempts to download a module
This module has a fake Zip header of 0x10. We have seen such examples before, but they are saved in the Registry (Figure 7) and they are the same.
After the Bot is executed in the module, it is saved to the Registry. Then, the Bot sends the following information to the C & C Server:
Id: % lu | tid: % lu | result: % lu
A real example is as follows:
Id: 150233784 | tid: 106 | result: 1
The id here is the same as that in the sent data packet. Tid is at the 04 offset of the block, and 106 is the hexadecimal 6A. If the module is successfully executed, the result value is 1; otherwise, the result value is 0. Figure 16 shows network traffic.
Figure 16: Network Traffic
The Cmd type of other blocks is 1, which indicates "Download exe" and spread other malware. The Bot will try to download the exe and run it as a temporary file. The Exe file is not encrypted as the module (figure 17 ):
Figure 17: exe is not encrypted
After execution, the Bot will communicate with the C & C server.
Figure 18: communication between a Bot and a C & C Server
We have seen a module named "r. pack. What does it do during execution? Are other types of modules installed?
Vi. Modules
In the network traffic of another variant, at least two other modules have been seen (figure 19 ). There are 3 modules in total, as shown below:
Module file name |
Underground module name |
Underground description |
Price |
F. pack |
Formgrabber |
Without the injector, http/https, all browsers including Chrome |
$500 |
R. pack |
Ring3 RootKit |
$300 |
S. pack |
Socks4 |
NA Complete |
NA |
Figure 19: two modules observed
1. r. pack
This r. pack is ring3 rootkit, which injects all running processes and hooks the following APIs to hide itself:
ZwResumeThread
ZwQueryDirectoryFile
ZwEnumerateValueKey
2. f. pack
This module is used for information collection. It creates a thread to initialize and monitor a named pipeline. Once data enters the pipeline, the thread will parse it and communicate with the C & C server through a different URL link. (Figure 20)
Figure 20
The thread replaces the image. php entry of the default C & C server with fg. php, and then adds a parameter id, which is the same as the id of the first package.
The content of the sent package is base64 encrypted (the same as that of the previous package ). After decryption, the data is as follows:-The config C & C server will respond with formatted data. The algorithm is the same as the previous response packet, but the RC4 key here is not taken from the id, instead, the RC4 key used for sending the package.
The decrypted format is as follows:
Next, like r. pack, it injects all running processes and hooks the ZwResumeThread API. Check the process name. Once the following four Web browsers are found, the corresponding APIs are hooked to collect information:
Iexplore.exe |
WINNET. dll HttpSendRequestW HttpSendRequestA |
Opera.exe |
RtlFreeHeap |
Firefox.exe |
Nspr4.dll PR_Write |
Chrome.exe |
ZwReadFile |
All data after the POST field will be checked. If all the conditions are met, the data will be sent to the named pipe. The thread that monitors the named pipeline will continue to verify the captured data based on the relevant format and then send it to the C & C server.
3. S. pack
This module acts as a local proxy and has an export function Report to display its own information (Figure 21)
Figure 21
This module opens the local port 0438 h (1080) and waits for a remote connection. If the affected machine is behind the firewall, this will not work. The destination IP address and port are in the response packet.
7. Another special Variant
The response package 22 of another variant of Andromeda is shown.
Figure 22
We can see that it does not have Cmd type 2, only "Install exe" Cmd type 1 and "Update bot" Cmd 3. At this time, this bot is only used to distribute other malware (such as ZeroAccess, Kelihos, FakeAV, and so on)
VIII. Conclusion
We have witnessed the changes made by Andromeda bot. It is flexible and dynamic. By installing different modules, You can enhance their functions in different fields. It can also efficiently distribute other malware. It uses multiple RC4 keys to encrypt communication with the C & C server, making it difficult to track it.
In addition, different botnets are combined to spread, so infected machines are exposed to greater risks. This poses a serious problem for effective detection and removal of infected machines.
The story of cats and mice continues. As mice become smarter and more flexible, what about cats?
(Full text)