Apart from randomized side-effects that the new trojan leaves on a system, including its ability to morph in order to avoid hash-based detections (well, hash-based detections never worked against ZeuS anyway, given the sheer volume and frequency of the generated samples and the variety of used packers), it seems that this time a great care was taken in protecting its configuration files.
The trojan now uses more layers in order to decrypt its configuration files.
Shrek: Onions have layers. Ogres have layers... You get it? We both have layers.
Donkey: Oh, you both have layers..
The new decryption steps are illustrated below:
It starts from initializing a 256-byte key table. At first, its bytes are set to value N, where N is a position of the byte in the key table (from 0 to 255).
Next, the code utilizes a large permutation table - a dynamically constructed table with a variable size around 40,177 bytes, in order to generate a new key table.
The newly generated key table is then used to decipher (RC4) another dynamically constructed table, called in the scheme above a "small table".
Once deciphered, the small table will contain both the configuration file URL and a new key table to decipher (RC4) the configuration file that the trojan requests from the remote server.
The new key table is stored inside the small table at a variable offset.
Due to polymorphic nature of the trojan, the locations of the large permutation table, encrypted small table and the offset of the key inside the decrypted small table are random.
Nevertheless, these random values are recoverable from the heap memory of any process infected with ZeuS.
In order to decrypt configuration files of ZeuS 2.0 on a host infected with ZeuS (e.g. under a virtual machine), a special tool can be built.
The tool would firstly need to identify ZeuS heap pages with the signatures and then check for the presence of the following code within the same ZeuS page:
// 55 push ebp
// 8B EC mov ebp, esp
// 51 push ecx
// A1 ?? ?? ?? ?? mov eax, ds:image_base
// 8B 0D ?? ?? ?? ?? mov ecx, ds:dwSmallTableOffsetVA
// 56 push esi
// 8D 34 01 lea esi, [ecx+eax]
// A1 ?? ?? ?? ?? mov eax, ds:XX
// 8B 0D ?? ?? ?? ?? mov ecx, ds:dwLargeTablePtrVA
// 89 4D FC mov [ebp+large_table_ptr], ecx
// 83 F8 02 cmp eax, 2
// 76 41 jbe short XX
// 57 push edi
The 1st wildcard (??) in the listing is the virtual address of the allocated page within the host process.
The 2nd wildcard is the virtual address of the small table offset within the same injected page; for example, the small table offset could be 0x33000. The first word of that table is the size of the large permutation table, with the actual small table following that word. The size of the small table is constant – it is 700 bytes in size.
The 4th wildcard in the listing is the virtual address of the large permutation table within the infected process. It is normally allocated as a separate heap page within the same host process.
Another offset still needs to be recovered from the identified malicious heap page – it is the offset of the key within the decrypted small table that is used to decipher (RC4) the configuration file itself. The value of this offset varies from 0 to 255.
To locate that offset, the infected memory page can be scanned for the presence of the following code:
// 8B 03 mov eax, [ebx]
// 56 push esi
// 57 push edi
// C6 45 FF 00 mov [ebp+flag], 0
// 85 C0 test eax, eax
// 74 6E jz short quit
// 8B 7B 04 mov edi, [ebx+4]
// 81 C1 ?? 00 00 00 add ecx, bKeyOffset
// 51 push ecx
// E8 ?? ?? ?? ?? call dec_rc4_xor
// 89 43 04 mov [ebx+4], eax
// 85 C0 test eax, eax
The key offset is the first wildcard in the listing above.
Once the tables and the key offset are fully recovered from the memory of an infected process, the tool can now decrypt the configuration file by using decryption algorithms derived from ZeuS via reverse engineering.
To assist those researchers who need to decrypt and analyze the contents of the ZeuS 2.0 configuration files, the ZeusDecryptor tool is available for download here.