Deep inside the King

Everybody knows Zeus, the king of “banking trojans”. If you are in the business of protecting banks from Zeus, you are probably interested in analyzing the configuration file of each Zeus C&C in order to understand how the bot actually works. Much has been written on Zeus and there is a plethora of technical articles and a couple of great posts [1, 2] on the ThreatExpert blog where they show us how Zeus uses its configuration file giving us a pretty much useless decryptor. Yet there is still some confusion about it and currently there are no useful tools that I’m aware of to help in automating the extraction and analysis of Zeus configuration files.
Zeus makes use of an RC4-encrypted configuration file. The file is downloaded from the C&C using an URL encoded with a static algorithm. Once downloaded, the configuration file is decrypted using a 256-byte key that is different for each C&C. Since the URL encoding mechanism is known, it is possible to search for the URL within the address space of a Windows process  injected by Zeus and locate the decryption key using an offset from there (-0x102).

This (ugly) code implements the mechanism.

On a Zeus infected machine, the encrypted configuration file is downloaded and three files are created:
  • zeus.enc: the encrypted configuration
  • zeus.raw: the decrypted configuration
  • zeus.key: the encryption key
The decrypted configuration (zeus.raw) is a block-based format with nested blocks, where each block has its own meaning and structure. It’s not enough to just dump the ASCII characters in there like the ThreatExpert decryptor does. To understand how the bot works, you need to parse it and convert it in a useful format.

This (ugly) code
is a parser for the Zeus configuration file that converts it to XML.

Here is a sample of the output.

The way I used to extract and decrypt the configuration file actually works on a subset of the Zeus versions not including the last one, it’s pretty much the same way the ThreatExpert decryptor works. In a future post I’m going to show a totally different method to achieve the same result working for the latest Zeus version too.

This entry was posted in Code and tagged , , . Bookmark the permalink.