Threat Research

ZeuS: Bot to Master early communication protocol (Part one of two))

By Kyle Yang | October 28, 2010

We’ve just spent two days looking into the ‘new’ variant of Zbot, a.k.a. ZeuS, the infamous crimeware kit. There are many interesting features, like the VNC plugin, API hooks, ftp password stealer, etc. In this series of posts, we’ll focus on the communication protocol between the bot and its Command & Control Server, in the early stages of infection.

Pre-configuration data, hardcoded and encrypted in the bot binary, contains the URL of a configuration file to download, and the key to decrypt it (among other parameters, that we may consider in a future blog post). Once the configuration file has been taken care of, the bot reports some info about the infected computer to the C&C server. The server in turns sends back some commands to the bot. Let’s details those 3 phases.

Locating and decrypting the configuration file:

This is an essential part of the bot’s setup. This is done as follows:

dotThe whole original zbot binary file is loaded into memory, via a call to the API ReadFile.

dotTwo data blocks are located (at fixed offsets):** Block A** and Block B.

dotBlock A is XORed with Block B (the decryption key), to obtain a clear text data block that contains the configuration file URL and a RC4 table, located at an offset that varies from binary to binary.

Note: In RC4 terms, this table is called a permutation (of all the 256 values a byte can take), and is used to generate a bitstream, in turn used as the XOR key to cipher/decipher messages as they come and go. To certain aspects, it can be considered as a key (although formally, an actual RC4 key is something else).

The configuration file is downloaded from the C&C server and loaded in memory.

dotThe** RC4 table** mentioned above is used to decrypt the configuration file. The resulting “clear text” is actually not ASCII text at all, but a binary structure:


Figure 2 - Decrypted Zbot Configuration Data Structure

The corresponding data structure may be defined as the following:

struct {

BYTE RandomBytes[20];

DWORD DataLength;

DWORD Unknown;

DWORD DataBlockCount;



DWORD BlockTag;

DWORD CompressTag; // Compressed if CompressTag & 1 == 1

DWORD CompressedDataLength;

DWORD OriginalDataLength; //if CompressTag & 1 == 0, then CompressedDataLength = OriginalDataLength

BYTE Data[DataLength];

} DATABLOCK[DataBlockCount];


BlockTag defines the type of configuration data contained in the block; it can be any of the following:

0x4e21 - Builder Version 0x4e22 - Update URL for the Bot binary 0x4e23 - DropZone URL 0x4e24 - Update URL for the Configuration, web inject followed 0x4e27 - Target URLs for the browser html injection attack (eg:,, etc...)

Note: This list is not exhaustive; furthermore, BlockTags meanings seem to vary from version to version. Especially, the scripts used for the html injection appear in blocks with varied BlockTags.

dotDecompress the DataBlocks that need to be, with a rather uncommon decompression algorithm called unrv2b.

At this point, all the configuration data exists in “clear text” in memory. It can be read, and the bot can act accordingly. But before that, as a good loyal soldier, it reports on the situation to its C&C server. This is what we’ll address in next post. Stay tuned!

Guillaume Lovet contributed to this post.

** **


Join the Discussion