2014-05-01
Abstract
Neurevt first appeared over a year ago – its many components cover a large number of the most popular malicious functionalities, including downloading malware, DDoS attacks and website sniffing. He Xu discusses the major changes that have been introduced into the most recent generation of the botnet.
Copyright © 2014 Virus Bulletin
The infamous Neurevt (a.k.a. Betabot) botnet first appeared in March 2013. It has many components, covering a large number of the most popular malicious functionalities – such as downloading malware, DDoS attacks and website sniffing. In this article, we discuss the major changes that have been introduced into the latest generation of the botnet.
The latest version of Neurevt doesn’t execute its malicious code directly, but instead acts as a normal loader (Figure 1). It finds the encrypted block (shown in red in Figure 1) by looking out for the 0x10 length signature in the block’s header. Then it extracts the module binary from the block and places it in a newly allocated section of memory (the block structure detail is listed below as enc_block). It then replaces the module’s default config block with its own local config block (shown in blue in Figure 1) – the block size may differ a little between loader and module.
typedef struct enc_block { CHAR Signature[0x10]; DWORD key; DWORD EncSize; DWORD DecSize; CHAR Block[*] };
Next, the loader updates the values of the two DWORD bitsmarks in the replaced config block, changing them from the default 0 to 1 (see Figure 2), and loads the config block according to the module’s PE structure. Finally, the loader calls the entry point of the module.
The module cannot run independently because it requires the loader’s initialization. In addition, its structure differs from the standard PE structure. Let’s look at the section table (Figure 3).
The raw sizes are all too large to run independently. As a result, the loader and module are inseparable. This also means that the embedded binary can remain stable for a long time without needing to change anything. This is much easier for maintenance.
The previous variant’s preferred injection target was C:\windows\system32\wuauclt.exe, but the latest version injects its main code into a newly created process, C:\windows\explorer.exe.
However, it does not modify the entry point code of the compromised process or create a new remote thread starting from its malicious code. Instead, it modifies ntdll.dll’s export function ZwContinue (Figure 5), and then jumps to a tiny section of newly allocated memory to recover the API’s original code (Figure 4) and create a new thread which executes the malware’s major code.
To avoid deep analysis and tracking by security researchers, the bot copies various API codes to itself – in particular those that start with ‘Zw’ and which are mostly ntdll.dll export functions. This means that most API breakpoints don’t work for Neurevt.
Let’s look at an example for calling the ZwResumeThread API. The default API code is shown in Figure 6.
After the bot’s modification, all of the code is copied to local memory, as shown in Figure 7.
Things are a little different because the bot merges the code of two APIs together locally. This could be used as a possible clue for indicating that a system has been infected by Neurevt. As a backup, the bot still supports normal API calls when the copy code mechanism fails.
Since the special ClsID directory name feature has become well known, the bot has stopped using it. It still replicates itself in the %COMMONPROGRAMFILES%\ directory, but the subsequent child directory is hard-coded in the binary, so different variants have different directory names. The following list shows several of the replication paths that we have observed. The filename is random on each replication attempt:
%COMMONPROGRAMFILES%\CreativeAudio\jnmhzdjtt.exe
%COMMONPROGRAMFILES%\nvv svc\rjmynangs.exe
%COMMONPROGRAMFILES%\Winsys\nrmhzdjtb.exe
%COMMONPROGRAMFILES%\WindowsUpdaterAgent0\jwvzdqgtr.exe
Without the protection of the special ClsID directory name, the bot adds an advanced inline hook feature in order to hide itself.
To make detection more difficult, the bot adds a random parameter to the end of its C&C link. It will randomly select one of the following parameters while communicating with the C&C server:
Parameter | Examples |
---|---|
null | */order.php |
id | */order.php?id=<number> |
pid | */order.php?pid=<number> |
page | */order.php?page=<number> |
Our investigation suggests that these parameters are actually meaningless. The number values do not provide real information relating to the system. However, this information gives us another tip for identifying the latest generation of the malware.
Let’s look at the last variant first. The earlier variant uses fixed parameter names in the post content (see Figure 8). The initial package uses ps0, ps1, cs1, cs2 and cs3 to carry local information to the C&C server. This makes it easy to detect according to these parameters.
The encryption for the ps1 value is RC4 and the key is taken from the initial config block. Figure 9 shows the sending package after decryption.
The cs1, cs2 and cs3 values are encrypted using a simple XOR encryption (see Figure 10). The DWORD keys are hard-coded in the bot’s code and should be the same among most variants: \x1D\xCC\xB9\xEA.
Now let’s get back to the latest generation, which makes detection significantly more difficult by changing most of the parameter names to random strings (Figure 11). The number of parameters has increased from five to eight – so it can carry more information.
There are still some small signs that could be used by a filter to detect the package – for example, starting from the fourth parameter, the name tail is always a number, and it increases by one each time.
The encryption has changed too, and can be categorized in two parts. The first (or the second) parameter whose value is not only numbers is added to a random key that will be combined with a hard-coded key as the final RC4 key to decrypt the third parameter (Figure 12) – which should be the same as ps1 in the previous variant.
The second part is for decryption of the name-tail-number-increasing parameters: the encryption is XOR with a fixed DWORD key \x22\xF0\x71\xC2 that has already changed from old variants.
So finally, we get the complete plain text of the sending package. Comparing this with Figure 10, the bot could collect two more pieces of information about the compromised system, such as CPU and video card information. We can see that the bot is executed under the VirtualBox system, so the C&C server could refuse its connection or never give a real response.
The received package structure and algorithm has also been updated. First, the two-byte fixed signature at the start, \xD8\xFF, has been removed, so the total package could be treated as a random data block before decryption.
The current structure is as follows:
typedef struct recv_pack{ DWORD HdrKey; DWORD BodyKey; CHAR Header[0x5C]; CHAR Body[*] };
The detailed Header structure is the same as before, as is the body. However, the key-generation mechanism has changed slightly – the bot will not use the hard-coded key directly, but uses a XOR db algorithm with db key ‘\xCB’ to decrypt the header. It uses another hard coded key combined with the second DWORD value and then uses a XOR db algorithm with db key ‘\x1F’ to decrypt the body.
Figure 14 shows the final decrypted pack.
As we have seen, the C&C server only uses the first block for executing specific commands. It spreads other malware using the .dwfile command with additional parameters. Our investigations show that the current variant is spreading the Andromeda and Dorkbot malware.
The block types vary according to the size list in the config header. Currently, the bot only uses the first four blocks, which is the same as the previous variant. The first block is for commands, the second is for the domain blacklist, the third is for the website sniffer, and the fourth block is for updating the configuration.
The bot could support 0x25 / 38d different commands and there is a trick: the bot does not save any command string locally, only a checksum list for comparing the calculated command string value. So unless we received the actual command, we would not know it is plain text.
Since we first saw Neurevt we have collected the following commands and their related indexes:
Command | Index | Description |
---|---|---|
.dwfile | 0x05 | Download and run other malware |
.update | 0x07 | Download and run its update binary |
.botkill | 0x11 | Erase all local system information |
.ddos | 0x12 | DDoS attack |
.browser | 0x19 | Open Internet browser |
In the second block, the bot has changed the fake IP from the local 127.0.0.1 to a real Internet IP – currently only that belonging to Google, so it likes a special DDoS.
With its newly designed random parameters, Neurevt’s communication with its C&C server is much safer than before. The modification for encrypting the sending and receiving of packages, could cause many vendors’ detections to fail. The compatible commands structure could prompt previous purchasers of the malware to update to the latest version and without too much adaptation. Needless to say, we will continue to track the activity of the Neurevt botnet.