This application requires Javascript for optimal performance.

Secrets of the Ozdok/Mega-D Botnet

Research and Analysis: Doug MacDonald

Index:


Introduction

The Ozdok botnet, also known as Mega-D, has gone through some difficult times in the last few months.  Despite its low profile, last year it was one of the major spam distributors, ranking number two on some lists. Then in November 2009 researchers at FireEye orchestrated a takedown of Ozdok's Command and Control servers, shutting down the botnet completely. But in the following weeks it was brought back to life, and today Ozdok has recovered its former status as a top spam bot.

The purpose of the Ozdok botnet is to generate spam. To do this it uses a network of servers to control the bots and distribute spam templates. In this analysis we will look at the structure of this network, the messages passed through it and how the final product, the spam, is generated. Note that some details of the bot's behaviour may vary with different versions, but generally Ozdok rarely changes in any substantial way.


Bot Installation

The bot may be delivered to its victims by any of the usual methods, for example by a spam campaign or by previously installed malware. The size of the bot program is about 100k, not too large for easy distribution. When the bot is executed, either by a user or automatically, it takes the following steps to install itself:

  • The bot creates a new "svchost.exe" process and inserts its own code into this process.
  • A batch file named "[8 digits].bat" is created in the desktop folder and executed.
  • The bot code is copied to an Alternate Data Stream (ADS) on the hard drive, where it is hidden from the user and possibly from some AntiVirus software. Because ADS is used, the bot program can only be saved on NTFS file systems. On computers with FAT32 drives the bot exists in memory, but it only runs until the system is rebooted.
  • A registry key is created to hold the bot's ID number, "HKLM\Software\Microsoft\Windows\CurrentVersion\Fci". This is a hidden registry key, where the "Value" name is longer than the 255 character maximum, so the "Data" cannot be viewed with regedit.
  • The original bot file and the batch file are deleted.
  • At this point the bot announces itself to the botnet, gets its orders and goes to work.

Joining the Botnet

When the installation is completed, the Ozdok bot immediately tries to join the botnet. Figure 1, which can be seen below, shows the general structure of the botnet from the bot's point of view.

  • The box at the upper left in Figure 1 represents the bots, a large number of infected computers running the Ozdok malware.
  • At top center is the C&C Server (Command and Control), which sends commands to the bots to control the botnet.
  • Below the C&C is the Email Test Server. This server is only used to test the ability of the bot to send email, before trying to send spam. If the email cannot be sent the bot continuously retries until the test is passed.
  • At bottom center is a box that lists the STS Servers (Spam Template Servers). These servers supply the bots with spam templates. The templates contain details of the spam email, target email accounts and lists of mail servers that can be used to send it.
  • At the upper right we have the DNS Servers, used by the bot to connect to the mail servers. These appear to be legitimate servers, probably chosen for their ability to handle large numbers of DNS queries.
  • The Mail Servers used by the botnet are shown at middle left, and below are the Targeted Email Accounts the spam is sent to. Images used in the spam emails are planted on the Legitimate Online File Storage sites at right center.
  • When someone, who has received the spam, clicks on one of the embedded links they are sent to the Online Sales Site, shown at bottom right.

The bot connects outward to the botnet servers, and receives its commands as replies. This is neccessary because in most cases the bot will be on a computer that is behind a router or firewall, so that inward connections are not possible.




Figure 1: Botnet Structure

Here is an timeline of the process a bot must follow in order to log into the botnet:

  • To join the botnet, the bot sends a login message to the C&C Server (Command and Control). The C&C replies with a unique ID number for the bot. The bot will need this ID number to communicate with the botnet.  The analyzed bot contains only one C&C server URL, and if no connection can be made it just keeps retrying it.
  • From this point forward the bot continues to check the C&C for new commands every 60 seconds.
  • Next the C&C sends the bot the URL of the Email Test Server and tells the bot to perform an email test. The bot does a DNS query to get the MX record for the mail server, and sends the test email. The email does not contain any special information about the bot or the infected host, so this is just a mailing test. If the test fails it will be retried until it succeeds.
  • Now that these preliminaries are completed, the C&C sends the bot the IP address of one of the STS Servers (Spam Template Servers). The bot connects to this server and downloads a spam template. The template contains the layout of the spam to be sent and target email addresses to spam, usually 2000 of them.
  • At this point the bot starts to send spam to the targets found in the template. When it finishes spamming a template, it sends a detailed report to the STS and downloads an update template, with more targets.
  • During analysis, each spam email contained hidden links to an Online Pharmacy Sales site. The recipient of the spam may click on one of these links and be offered the opportunity to purchase a variety of products.

Botnet Message Formats

The real power of a botnet lies in the bots. To harness this power the botnet controller must be able to command the bots to work in a coordinated manner. The message system of the botnet is the means by which this is accomplished. The messages that are passed between the Ozdok bots and the botnet servers tell a large part of the story about how this botnet really functions.

Ozdok botnet messages are transmitted over port 443, which is normally used for HTTPS secure web browser connections, employing the SSL protocol. Ozdok ignores the normal useage and communicates with its own protocol. An example of an Ozdok message can be seen below, as it was captured by a network sniffer. Only the SSL data part of the packet is shown.

8 17:38:13 192.168.1.83          72.52.210.130         SSL      Continuation Data Len: 42
00 05  db fd 37 7f 11 01 b9 e5 ea  e5 fe e8 06 5b 2d 3a ea  e5 fe e8 06 5b 2d 3a 
db c7 5e 0f 61 9b b0 a3  76 04 60 fe 88 64 a8 f2

The first two bytes in the data, "00 05", indicate the number of 8 byte blocks in the message. The rest of the message is encrypted, as the lack of null bytes tends to indicate. (Encryption randomizes the data, so that only one byte in 256 will be "00". Normal program code or data tends to have far more null bytes, though this is not always the case.)

Each of the 8 byte blocks is encrypted with standard DES (Data Encryption Standard) in ECB mode, using the functions in "ADVAPI32.DLL". The key is hard coded into the bot, so that all messages for that bot version are in the same key. ECB stands for Electronic Code Book, a mode where identical plaintext blocks are encrypted to identical cipher blocks. The effect of this can be seen in the example above. The block  "e5 fe e8 06 5b 2d 3a ea" is repeated twice, and looking at other messages it can be seen in many places. It is not hard to guess that this is probably the encrypted form of "00 00 00 00 00 00 00 00", and in fact this is correct. Other blocks are not so easy to guess, but of course guessing is not neccessary.

An examination of the bot code quickly leads to the encryption key, which for these samples is "abcdefgh". It is pretty clear that the programmer who coded the bot was not very concerned with secrecy. Maybe the intent was to change keys with new bot versions, but the servers would also have to accomodate this change.

The decrypted messages reveal an internal structure that depends partly on the message type. The two messages below illustrate this. The first two bytes, in field A, have hard coded values that can be ignored. Field B, the second pair of bytes, (0x21 and 0x25) identify the message type or command. From this point the fields are different for each message type. In some cases the next byte may indicate a sub-type, for example field C (0x01) in the first message. In the second message field C contains other data.


01 00  00 21  00 00 00 01  00 19  73 65 6C 65 6D 65 6E 74 75 73 61 6B 73 2E 6F 72 67 00 00
|.A.|  |.B.|  |.C.......|  |.D.|  |.F....................................................|

01 00  00 25  ce 59 00 00  a8 d0 82 01  00 00 37 7c
|.A.|  |.B.|  |.C.......|  |.D.......|

The DES encryption must be done in eight byte blocks, so a message usually includes a few extra bytes to fill out the last block. These bytes are taken from the message buffer, which is not cleared before use, so they contain whatever old data happens to be left there. The "00 00 37 7c" bytes seen at the end of the line above is an example of this behaviour.


Botnet Messages

The list below gives some general information about the botnet messages seen during normal operation. The messages are divided into groups by source and destination. Note that some message numbers occur in more than one group, with one message being a response to the other. The message type numbers are shown as described in the previous section, usually with byte B alone (0x21), but sometimes including byte C (0x00-01).

Bot to C&C

  • 0x00-00  Bot message to log into the botnet.
  • 0x00-01  Bot message to check the C&C for new commands, sent every 60 seconds.
  • 0x16      Message with bot host info for the C&C, reply to 0x15.
  • 0x22      Email test result: good.
  • 0x23      Email test result: failed.
  • 0x25      Confirm that the bot received message 0x24.

C&C to Bot

  • 0x01     Ack bot "check in" message 0x00-01, includes ID numbers
  • 0x15     Request bot host info.
  • 0x21     Command the bot to do an email test.
  • 0x24     Message with a Spam Template Server (STS) address, where the bot can get a spam template.

Bot to STS

  • 0x1b     Request an update template.
  • 0x1c     Ack spam template received.
  • 0x1d     Request initial full spam template.
  • 0x1e     Message with spam results report.

STS to Bot

  • 0x1c    Message that delivers a spam template.
  • 0x1d    Tells the Bot that the STS is busy

Botnet Message Flow

Now that we understand the basic message format, we will look at the details of the messaging that occurs during the course of normal botnet activity. Generally the sections below follow the order of events for a newly installed bot.


First Contact and Email Test

When the bot malware is fully installed on a host computer, it connects to the C&C server and logs into the botnet. The C&C then tells the bot to carry out an email test, and when the test is done the bot reports the result to the C&C. This process is illustrated below in Figure 2. The hexadecimal numbers above the lines indicate the message type.




Figure 2: Bot Login and Email Test

The decrypted packet data below is from the first packet sent from the newly infected bot to the C&C server. Field B indicates the message type, with field C acting as a sub-type in this case, so this is labeled 0x00-00 in Figure 1. The ID1 field is set to nulls because no ID number has been assigned yet. The IP field contains the local address of the infected computer.

8 14:42:02 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 42
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 0000 0000 00 00 00 4d 00 00 00 2c c0 a8 01 53
|.A.| |.B.| C. |.ID1......................................| |.E.......| |.F.......| |.IP......|

The reply from the C&C is a message of type 0x01. It contains a unique ID for the bot, in field ID1. ID1 is used to communicate with the STS (Spam Template Server), and remains constant when the bot infected computer is shut down and restarted, with the value being saved in the registry. The C&C also assigns a second ID number, in field ID2, that is used by the bot when it contacts the C&C server. This number is reassigned by the C&C, with a new value, whenever the bot is restarted.

10 14:42:03 72.52.210.130         192.168.1.83          SSL      Continuation Data  Len: 34
01 00 00 01 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00 00 00 00 3c ce 59 00 00 a8 d0 82 01
|.A.| |.B.| |.ID1.........................................| |.D.......| |.ID2.................|

The TCP connection is kept open so that the C&C can send message 0x21, which starts the email test. Field F contains a URL to use for the mail test. The bot does a DNS MX lookup of field F to find the email server, then gets the server IP address and sends the test email. When the bot receives 0x21 it closes the TCP connection to the C&C.

11 14:42:03 72.52.210.130         192.168.1.83          SSL      Continuation Data  Len: 34
01 00 00 21 00 00 00 01 00 19 73 65 6c 65 6d 65 6e 74 75 73 61 6b 73 2e 6f 72 67 00 00
|.A.| |.B.| |.C.......| |.D.| |.F....................................................|
                               s  e  l  e  m  e  n  t  u  s  a  k  s  .  o  r  g

When the email test is successfully completed the bot sends message 0x22 to the C&C. Notice the use of ID2 when communicating with the C&C.

42 14:42:05 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 18
01 00 00 22 ce 59 00 00 a8 d0 82 01
|.A.| |.B.| |.ID2.................|

If the mail test fails, the bot sends message 0x23 back to the C&C. Then it waits for another 0x21, which has the same test URL that failed before, and the cycle repeats continuously. The analyzed bot does not seem to have any alternative email test server. Field C is an error code indicating the type of failure. 

34 16:26:56 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 18
01 00 00 23 40 00 27 4c a8 7d 00 00 b2 1f 4a 45
|.A.| |.B.| |.C.......| |.ID2.................|

When the infected computer is restarted, the messages in this section are all sent again. The only difference is that the ID1 field, in the first message from bot to C&C (0x00-00), contains the actual ID1 number instead of nulls. The message below shows how this works. The bot saves the ID1 number in the registry for this purpose.

8 17:58:17 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 42
01 00 00 00 00 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 0000 0000 00 4d 0000 00 2c c0 a8 01 53 
|.A.| |.B.| C. |.ID1........................................| |.E......| |.F......| |.IP......|


Maintaining Contact with the Botnet

After the initial login, the bot maintains contact with the botnet by polling the C&C every 60 seconds, to check for new commands. The diagram below shows this in action, as the bot polls, and then recieves a new command from the C&C.




Figure 3: Maintaining Contact

The first message here (0x00-01) is sent by the bot to check in with the C&C, and to give the C&C an opportunity to send commands to the bot. This message is sent every 60 seconds as long as the bot program continues to run. Notice that ID2 is included to identify the bot.

57 14:43:03 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 26
01 00 00 00 01 ce 59 00 00 a8 d0 82 01 00 00 00 00 
|.A.| |.B.| C. |.ID2.................|

The C&C server acknowledges the bot's check in with message 0x01, which is the same as the message sent in reply to the initial contact. It contains the same two ID numbers.

59 14:43:03 72.52.210.130         192.168.1.83          SSL      Continuation Data  Len: 34
01 00 00 01 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00 00 00 00 3c ce 59 00 00 a8 d0 82 01
|.A.| |.B.| |.ID1.........................................| |.D.......| |.ID2.................|

At this point the server will close the TCP connection if there are no commands for the bot. In this example there is a command, so the connection is kept open and message 0x15 is sent. This message is only seen once, immediately after the initial login.

61 14:43:03 72.52.210.130         192.168.1.83          SSL      Continuation Data  Len: 10
01 00 00 15
|.A.| |.B.|

The bot replies with message 0x16, containing some additional information about the infected computer. Field C gives the length of the data in bytes, followed by various other information, with the last field containing the local IP address of the bot.

63 14:43:04 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 58
01 00 00 16 ce 59 00 00 a8 d0 82 01 00 24 47 65 6e 75 80 00 00 00 00 00 36 05 00 05 00 01 0a
|.A.| |.B.| |.ID2.................| |.C.| |.Data............................................

  28 00 02 00 00 00 03 7d f0 00 01 dc 94 00 12 c0 a8 01 53
  ...........................................| |.IP......|

The bot continues to poll the C&C server every 60 seconds by sending message 0x00-01. Following the message above, the C&C sends two additional commands, 0x18 and 0x0e. These messages are only sent after the first connection to C&C. Both are ignored by the bot and it appears that they may be intended for a different version.


Getting the Spam Template

With these preliminaries over, it is time for the bot to get the spam template. The Ozdok spam template contains more than just the email format information. As we will see later it also carries all of the information needed to send spam.  Figure 4 shows an overview of how the template is obtained.

An interesting difference between C&C messages and STS messages can be seen here. For messages between the bot and C&C, the reply is usually the next higher message number. For example C&C message 0x24 gets bot reply 0x25, message 0x21 gets reply 0x22. For messages between the bot and STS, the reply is often the same message number. For example message 0x1c from STS leads to bot message 0x1c, and one reply to message 0x1d is the STS busy message 0x1d. This seems like the result of two programmers working without a proper message system design.




Figure 4: Getting the Spam Template

The first two messages in Figure 4 are the ones sent by the bot to check the C&C for new commands. Following these, the C&C sends message 0x24, with the IP address of one of the Spam Template Servers in the third field (STS.IP). The value in field C is 0x01bb (443 decimal), the TCP port to be used by the bot when connecting to STS.

181 14:52:06 72.52.210.130         192.168.1.83          SSL      Continuation Data  Len: 18
01 00 00 24 43 e1 9a b0 01 bb 00 00
|.A.| |.B.| |.STS.IP..| |.C.......|

In reply the bot sends message 0x25, to tell the C&C that is has the information. This is another simple C&C ack message, with just the message type and ID2.

182 14:52:06 192.168.1.83          72.52.210.130         SSL      Continuation Data  Len: 18
01 00 00 25 ce 59 00 00 a8 d0 82 01
|.A.| |.B.| |.ID2.................|

Using the STS IP address, the bot sends message 0x1d to the Spam Template Server to request a new spam template. Notice that ID1 is used to talk to the STS.

189 14:52:06 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 26
00 01 00 1d 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00
|.A.| |.B.| |.ID1.........................................|

STS replies with message 0x1c, which includes the spam template and is continued over as many packets as are needed. The template data does not contain all the target addresses available, just the first 2000. This list will be augmented by further downloads. The number in field C is a template identifier that is used when reporting spamming results. Field E is the length in bytes of the template data. The template data is compressed with zlib, which is compiled into the bot.

191 14:52:07 173.212.241.58        192.168.1.83          SSL      Continuation Data  Len: 1460
01 00 00 1c 32 e6 13 00 00 01 67 0e 00 00 7e c0 78 9c 9c bd eb b2 dc 36
|.A.| |.B.| |.C.......| |.D.......| |.E.......| |.Template.............>

When the template has been downloaded the bot sends message 0x1c to the STS as an acknowledgement. This is another simple ack message,  sent with ID1 because it is going to STS.

226 14:52:07 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 26
01 00 00 1c 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00
|.A.| |.B.| |.ID1.........................................|


Spamming and Reporting

With the template in hand, the bot spawns a new thread and begins to send spam. While the spam is being sent the bot occasionally reports back to the STS with progress information and details of any mailing errors. This reporting is important to the spammer, because payment ultimately depends on how much spam is actually sent. Figure 5 shows a template being spammed, reports being sent and an update template being obtained when the first one is completed.




Figure 5: Report and Get New Template

After spamming for some time, the bot sends a report to STS showing what has been accomplished so far. Reports may be sent several times while a template is being processed, if there are problems and it takes some time to finish. If all goes well only one or two reports will be sent. The report is sent as message type 0x1e. Field D contains the template ID that we saw being delivered with the template download (message 0x1c above). Field E below is the number of email addresses in the current template (0x7d0=2000), and does not change. Field F is the number of spam successfully sent so far. The numbers in fields G to X show how many spam are in various intermediate states and failure states.

In this test, email could not be sent, so most of the spam has not moved beyond state G (waiting for mail server), while some went to state I. The number actually sent, in field F, is zero. The total number of spam to be sent, in field E, is equal to the sum of all the following fields.

1612 14:54:49 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 106
01 00 00 1e 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00 32 e6 13 00 00 00 07 d0 00 00 00 00
|.A.| |.B.| |.ID1.........................................| |.D.......| |.E.......| |.F.......|

00 00 07 29 00 00 00 00 00 00 00 a7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|.G.......| |.H.......| |.I.......| |.J.......| |.K.......| |.L.......| |.M.......| |.N.......|

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|.O.......| |.P.......| |.Q.......| |.R.......| |.S.......| |.T.......| |.U.......| |.V.......|

00 00 00 00 00 00 00 00
|.W.......| |.X.......|

The bot continues to try to send spam, and while it is working it sends more spam reports, with updated totals in each field. The example shows that the number of spam in state G has dropped, but state F is still zero so none have actually been sent. Instead they have moved to state M and state Q, which indicates that actions that they were attempting have not been completed.

3055 14:58:57 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 106
01 00 00 1e 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00 32 e6 13 00 00 00 07 d0 00 00 00 00
|.A.| |.B.| |.ID1.........................................| |.D.......| |.E.......| |.F.......|

00 00 01 f5 00 00 00 00 00 00 00 a7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ea 00 00 00 00
|.G.......| |.H.......| |.I.......| |.J.......| |.K.......| |.L.......| |.M.......| |.N.......|

00 00 00 00 00 00 00 00 00 00 00 4a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|.O.......| |.P.......| |.Q.......| |.R.......| |.S.......| |.T.......| |.U.......| |.V.......|

00 00 00 00 00 00 00 00
|.W.......| |.X.......|

When the bot decides that all of the targets in the current spam template have been tried, successfully or not, it gets an update template from the STS server that it is currently working from. The update template only contains more addresses to spam, all of the other template data fields are blank. The message type to get an update is 0x1b, a different command from the one used to get the first template, but with the same format.

4059 15:01:34 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 26
00 01 00 1b 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00
|.A.| |.B.| |.ID1.........................................|

The server replies with message 0x1c, which has a new template ID (in field C), along with the update template containing more target addresses. This is the same message type used to deliver the first template.

4061 15:01:35 173.212.241.58        192.168.1.83          SSL      Continuation Data  Len: 1460
01 00 00 1c f6 03 14 00 00 00 af 81 00 00 2a 6a 78 9c 8d 9d dd 96 e3 2a
|.A.| |.B.| |.C.......| |.D.......| |.E.......| |.F....................>

The bot sends message 0x1c to STS to acknowledge the download, as we have seen before. Then the bot spawns a new thread and starts to spam the email addresses in the update template. While this is happening the first spamming thread finishes its work and sends its last report to the STS. The report can be seen below. In this case most of the spam ended up in states M and Q, with field F still at zero because no spam was ever sent.

5267 15:03:58 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 106
01 00 00 1e 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00 32 e6 13 00 00 00 07 d0 00 00 00 00
|.A.| |.B.| |.ID1.........................................| |.D.......| |.E.......| |.F.......|

00 00 00 a5 00 00 00 00 00 00 00 a7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 d3 00 00 00 00
|.G.......| |.H.......| |.I.......| |.J.......| |.K.......| |.L.......| |.M.......| |.N.......|

00 00 00 00 00 00 00 00 00 00 00 b1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|.O.......| |.P.......| |.Q.......| |.R.......| |.S.......| |.T.......| |.U.......| |.V.......|

00 00 00 00 00 00 00 00
|.W.......| |.X.......|

To give a fuller view of the reporting messages, the example below is from a test run where the network was set up to allow the spam to be sent to a fake mail server. The number in field F shows that 0x2a3 (675) spam were accepted for delivery by the fake mail server when this report was sent. The mail server was disconnected after a few minutes, so that most of the spam (943) went to state G, with no response from the mail server.

31479 17:01:49 192.168.1.83          174.37.207.125        SSL      Continuation Data  Len: 106
01 00 00 1e 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00 da 8d 02 00 00 00 07 d0 00 00 02 a3
|.A.| |.B.| |.ID1.........................................| |.D.......| |.E.......| |.F.......|

00 00 03 af 00 00 00 00 00 00 00 27 00 00 00 00 00 00 00 6e 00 00 00 00 00 00 00 00 00 00 00 00
|.G.......| |.H.......| |.I.......| |.J.......| |.K.......| |.L.......| |.M.......| |.N.......|

00 00 00 00 00 00 00 db 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0e 00 00 00 00 00 00 00 00
|.O.......| |.P.......| |.Q.......| |.R.......| |.S.......| |.T.......| |.U.......| |.V.......|

00 00 00 00 00 00 00 00
|.W.......| |.X.......|


Botnet Error Handling

It is often possible to learn more about a botnet by observing it when an error happens than can be learned during normal operation. The examples here show how two different botnet connection errors are handled.  


Lost Syn Packet

The first example, illustrated in Figure 6, shows a case where the STS server failed to respond to a syn packet from the bot. The dotted lines between the bot and STS1 indicate the lost packet.




Figure 6: Lost Syn Packet to STS

The message at the top of the diagram, labeled "0x00-01 & 0x01 Check C&C", indicates the polling message exchange between the bot and the C&C that occurs every 60 seconds. This poll results in message 0x24 being sent being sent from the C&C to the bot, telling the bot to get a spam template from STS1.

Using the STS address included in the message, the Bot tries to establish a TCP connection with STS1, but the Syn packet sent to start the connection is lost (due to it being deliberately blocked in this test). The bot tries three times and then gives up.

After this disaster the bot continues to send polling messages to the check the C&C, but otherwise does nothing. These polling messages do not differ in any way from other polling messages. The bot does not tell the C&C what has happened.

But somehow the C&C discovers the problem and sends another message 0x24 with a new STS address, in this example the address of STS2. Sometimes the same STS address is sent, so that it seems it must be randomly selected. The time delay for C&C to send another 0x24 message is always very close to 6 minutes, suggesting that a timeout occurs.

The bot is now able to get the template from STS2 and go to work. Notice that message 0x1d is sent to STS2, not 0x1b, the message that was refused by STS1. Message 0x1d is used to get a new template from a new server, where 0x1b gets an update template from an STS server that is already in use. So it seems that different STS servers could carry different spam campaigns.

The unanswered question here is, how does the C&C know that it needs to send another STS address? The bot doesn't tell it. There has to be a hidden link between the STS servers and the C&C server. The simplest way for this to work is for each STS to notify C&C when a bot gets a template. In Figure 6 the dashed red line from STS1 to C&C is meant to indicate a notification message that was not sent. If there is no notification from the STS that the bot was told to contact, the C&C times out and sends another 0x24 message to the bot. When STS2 gets the template request (0x1d) it notifies C&C, indicated by the solid red line from STS2 to C&C. Of course their are more elaborate ways that the STS to C&C messaging could be done, but the the effect would be the same. 


Server Busy

The next diagram, Figure 7, shows another type of botnet failure. Here, the first STS server reports that it is too busy to supply template data to the Bot. This is a frequent occurrence during peak hours, when the largest number of infected computers are online.




Figure 7: Spam Template Server Busy

In this case the Bot is already spamming from a template obtained from STS1. Following the usual pattern the bot sends message 0x1e with a spam report, then it asks STS1 for an update template by sending message 0x1b.

11678 15:18:54 192.168.1.83          173.212.241.58        SSL      Continuation Data  Len: 26
00 01 00 1b 86 61 a4 f6 a3 25 df 11 85 67 f4 7e 37 7c 00 00
|.A.| |.B.| |.ID1.........................................|

The response from STS1 is to send message type 0x1d, which can be seen below. When this message is sent from STS to the Bot, it indicates that the STS server is busy, or for some reason cannot handle requests from the bot.

11681 15:18:54 173.212.241.58        192.168.1.83          SSL      Continuation Data  Len: 10
01 00 00 1d
|.A.| |.B.| 

After the message has been recieved by the bot, the current thread goes into a state where it sends polling messages to C&C (0x00-01 & 0x01) and waits for instructions. Other threads carry on with whatever they were doing. No special messages are sent to C&C to tell it what has happened.

After a delay of 30 to 120 seconds the bot receives message 0x24 from the C&C, with the address of a new Template Server, STS2. The bot contacts STS2 with message 0x1d, gets a new template and goes back to sending spam.

As with the case of the lost syn packet, the activity seen here can only happen if messages are being passed between the STS and C&C servers. In this case the delay time was much shorter, and much more variable, so it seems unlikely that a timeout is involved. A simple explaination is that when STS1 returns a Busy message (0x1d) to the bot, it also informs C&C. C&C then tells the bot to try another STS server. Sometimes the bot is told to use the same STS server, the one that was too busy, so again it seems the new server is chosen at random. What we are actually seeing in action here is a method for load balancing the STS servers. 


Templates and Spam

The spam template contains all of the information needed to send spam, including the email format, "To" addresses, "From" domains, subject lines, configuration, image links and much more. The spam template is in a tagged format, and is divided into two main parts, the TEMPLATE and the TEMPLATE_DATABASE. The TEMPLATE_DATABASE part is subdivided into several sections.

In most cases the number of entries in these sections remains the same in different templates, but most of the data will be changed. Many of the sections are not used in the spam email that is created from this template. Since data that is not used is always changed, it seems that the construction of the template must be automated. The size of the full spam template is usually about 85K bytes and the update template is about 30k bytes.


Template Details

Below is the first part of the spam template, which lies between the TEMPLATE tags. This part contains a top level outline of the email, with five variables that will be filled in to provide the details. Notice that both From and To will be set to the same value, the MAILTO_NAME. The _BODY_HTML variable points to a complex structure, that contains more variables to define its key parts. The variables here are defined in the second part of the spam template, the TEMPLATE_DATABASE.

{TEMPLATE}
From: Approved VIAGRA® Store <{MAILTO_NAME}>
Subject: {_DIKSBJ_0}
To: <{MAILTO_NAME}>
MIME-Version: 1.0
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset={_OUTLOOK_CHARSET6}">
</HEAD>
<BODY>
{_BODY_HTML}
</BODY>
</HTML>
{/TEMPLATE}


The second part of the spam template is the TEMPLATE_DATABASE section, which contains most of the template information. It is set between the opening {TEMPLATE_DATABASE} tag, and the closing {/TEMPLATE_DATABASE}.

The first section in the template database is the CONFIG section. Various timeouts are defined here, along with maximum values for some spamming parameters. A few operational settings are also made, for example LOGGING_LEVEL and TURBO_MODE.

{TEMPLATE_DATABASE}
{CONFIG}
MAX_SIM_CON:4
THREAD_COUNT:90
SMTP_CON_TIME0:40
SMTP_RCV_TIME0:60
SMTP_CON_COUNT:4
SMTP_ERR_LIMIT:4
FROM_ERR_LIMIT:3
DNS_SIM_COUNT:30
DNS_RSL_COUNT:3
DNS_RSL_TIMEO:20
STAT_TIMEO:30
LOGGING_LEVEL:1
TURBO_MODE:0
INQUEUED:3
SMART_FROM:1
ALLOWED:300
MAX_RECHARGE_QUEUE:5
UNCOMP_LIM:0
GRAYLIST_TIMEOUT:100
KILL_LAZZY_MX:0
SUPERVIZING:1
PTR_RSL:selementusaks.org
ACTUAL_RATE:13
CANVAS_MUTATION:0
INTER_LINE:13
PER_MSG_TMO:120
TO_EQUAL_FROM:1
{/CONFIG}


Next is the DOMAINS section, which contains a list of the email addresses that the bot is going to send spam to. All of the templates seen so far have had 2000 entries here. Further blocks of 2000 are added by the update templates. The example below shows only the first two entries, in a disguised format.

{DOMAINS}
ag*****@ sk*****.com
ak*****@ xy*****.com
...
{/DOMAINS}


Data from the DOMAINFROMS section is used to connect to the mail server of the spam target. The templates seen so far have all had 200 entries in this section. Using the first line from the example below, the bot would send "HELO  am*****.com" to the target's mail server.

{DOMFROMS}
le*****@ am*****.com:mail.am*****. com:66.3*.8*.155
la*****@ ad*****.com:mail.ad*****. com:24.7*.2*6.22
...
{/DOMFROMS}


The next two sections are tagged as FIRSTNAME and LASTNAME, and contain names to be used in addressing the spam. Each of these sections contained 50 names. They were not seen to be used by any of the tested samples. 

{FIRSTNAME}
Jared
Harvey
Arnold
...
{/FIRSTNAME}

{LASTNAME}
Cunningham
Hart
Snyder
...
{/LASTNAME}


The next section is tagged mac3, and specifies three character fonts. The fonts were not used by this template.

{mac3}
verdana
arial
tahoma
{/mac3}


After this is the BOOK section, with text that can be used to randomize the email body. There were always 200 lines of text in this section. In this example those lines contained a total of 4028 words or 23092 characters. This data was also not used by the template.

{BOOK}
A bypass pipe is being laid to divert the water away
from the junction to arrest further erosion .
NHL: Penguins, government officials reach "Impasse" over
new arena
...
{/BOOK}


The IMG section contained 20 links to image files that are used in the spam, but these files all contained the same image. The files are uploaded to legitimate file storage sites before the template is distributed. 

{IMG}
http:// mdjvxg.bay.livefilestore.com/y1ph...5t_0BMaZ/1.jpg
http:// usso5q.blu.livefilestore.com/y1pQ...Ybdml1iyB/1.jpg
...
{/IMG}


The DIKSBJ section contains subject lines for the spam. Notice, in the example below, that some lines have variables that allow the MAILTO_NAME or a random number to be inserted. Even the % off value is randomized.

{DIKSBJ}
Confirmation ref # [{DIGIT[6]}]
Important notice: Google Apps browser support
Important notice: Google
News on myspace
Special Discount 7{DIGIT[1]}% for {MAILTO_NAME}
Special Code for 7{DIGIT[1]}% for {MAILTO_NAME}
Electronic Discount Code 7{DIGIT[1]}% for {MAILTO_NAME}
New Private Message for {MAILTO_NAME}
Sales Event get 7{DIGIT[1]}% off
Your Future Order with 7{DIGIT[1]}% off retail
You have a new personal message
{/DIKSBJ}


The next section, OUTLOOK_EXPRESS6, contains 15 Outlook Express version numbers. This information was not used by this template.

{OUTLOOK_EXPRESS6}
6.00.2900.2869
6.00.2800.1437
... {/OUTLOOK_EXPRESS6} 


The SUBJECT section is used to set options for the formation of the subject line.

{SUBJECT}
Subj
{/SUBJECT}


The URLS section contains the links to the online sales site. These URLs are changed within a few hours, with the names always being formed from two concatenated words. All of them point to the same IP address, which is sometimes changed, but not very frequently. This was the only section where the number of entries varied.

{URLS}
feetclothe.com
dividegame.com
longnumber.com
counthas.com
learncan.com
{/URLS}


The TAGMAILFROM section defines an alternate way to format the From address, using data from the FIRSTNAME and LASTNAME sections. The next section, labelled nTagMailTo performs the same function for the To address. The formatting of the tag {nTagMailTo} is somewhat unusual.

{TAGMAILFROM}
"{_FIRSTNAME_0} {_LASTNAME_0}" <{MAILFROM_NAME}>
{/TAGMAILFROM}

{nTagMailTo}
"{_FIRSTNAME_2} {_LASTNAME_2}" <{MAILTO_NAME}>
{/nTagMailTo}


Next is the OUTLOOK_CHARSET6 section, which contains character set definitions that are randomly selected for use in the spam. 

{OUTLOOK_CHARSET6}
windows-1250
iso-8859-2
Windows-1252
iso-8859-1
us-ascii
{/OUTLOOK_CHARSET6}


In the MAIL_TO and MAIL_FROM sections, we have another set of To and From header formatting options.

{MAIL_TO}
{MAILTO_USERNAME}
@ {MAILTO_DOMAIN} <{MAILTO_NAME}>
{/MAIL_TO}

{MAIL_FROM}
{MAILFROM_USERNAME}
@ {MAILFROM_DOMAIN} <{MAILFROM_NAME}>
{/MAIL_FROM}


The BODY_TEXT section is used to define a plain text body. Here it sets an option for the email body to have no plain text part. 

{BODY_TEXT}
empty
{/BODY_TEXT}


Finally the BODY_HTML section provides the format for the spam email body. This is inserted directly into the main template. Notice that the link from the URLS section is included here several times, to provide more chances for the victim to be exposed the online sales site. An image link from the IMG section is also included.

{BODY_HTML}
<TABLE border=0 cellSpacing=0 cellPadding=0 width=632 align=center>
<TBODY><TR><TD><TABLE border=0 cellSpacing=0 cellPadding=0 width="100%">
<TBODY><TR><TD><TABLE border=0 cellSpacing=0 cellPadding=5 width="100%">
<TBODY><TR><TD style="TEXT-ALIGN: center" bgColor=#000000><FONT
style="MARGIN-LEFT: 5px" color=#ffffff size=1
face="Verdana, Arial, Helvetica, sans-serif"><A
style="COLOR: #ffffff; TEXT-DECORATION: none"
href="http:// {_URLS_0}/">Trouble viewing this mail? Read it
online</A></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR><TD style="TEXT-ALIGN: center"><BR><A href="http:// {_URLS_0}/"><IMG
style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px"
alt="No graphics displayed? Click here" src="{_IMG_0}"> </A><BR></TD></TR>
<TR><TD align=left>&nbsp; <TABLE border=0 cellSpacing=0 cellPadding=0 width="100%">
<TBODY><TR><TD style="TEXT-ALIGN: center"><P style="TEXT-ALIGN: center; MARGIN-BOTTOM: 0px"><FONT size=2
face="Verdana, Arial, Helvetica, sans-serif">The e-mail address is
{MAILTO_NAME}<BR><A style="COLOR: #0a86fa"
href="http:// {_URLS_0}/">Unsubscribe from this e-mail</A> | <A
style="COLOR: #0a86fa" href="http:// {_URLS_0}/">FAQ</A> | <A
style="COLOR: #0a86fa" href="http:// {_URLS_0}/">Advertise</A> | <A
style="COLOR: #0a86fa" href="http:// {_URLS_0}/">Privacy
Policy</A></FONT></P><P style="TEXT-ALIGN: center; MARGIN-BOTTOM: 0px"><FONT size=1
face="Verdana, Arial, Helvetica, sans-serif">Copyright {DIGIT[5]} Inc. All rights reserved.
</FONT></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
{/BODY_HTML}
{/TEMPLATE_DATABASE}


Spam Email Details

Here we see an example of the spam email in its final form, after all of the substitutions have been made. The parts that are changed in each email have been highlighted. The From and To addresses are identical, with some added text in From. The character set can take several values, but in appearance they are all about the same. In general the changable parts are just enough to make generic detection difficult.

From: Approved VIAGRA® Store <ag*****@ sk*****.com>
Subject: Your Future Order with 78% off retail
To: <ag*****@ sk*****.com>
MIME-Version: 1.0
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
</HEAD>
<BODY>
<TABLE border=0 cellSpacing=0 cellPadding=0 width=632 align=center>
<TBODY><TR><TD><TABLE border=0 cellSpacing=0 cellPadding=0 width="100%">
<TBODY><TR><TD><TABLE border=0 cellSpacing=0 cellPadding=5 width="100%">
<TBODY><TR><TD style="TEXT-ALIGN: center" bgColor=#000000><FONT
style="MARGIN-LEFT: 5px" color=#ffffff size=1
face="Verdana, Arial, Helvetica, sans-serif"><A
style="COLOR: #ffffff; TEXT-DECORATION: none"
href="http:// counthas.com/">Trouble viewing this mail? Read it
online</A></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR><TD style="TEXT-ALIGN: center"><BR><A href="http:// counthas.com/"><IMG
style="BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px"
alt="No graphics displayed? Click here" src="http:// nupdtq.blu.livefilestore.com/y1pY****N/1.jpg"> </A><BR></TD></TR>
<TR><TD align=left>&nbsp; <TABLE border=0 cellSpacing=0 cellPadding=0 width="100%">
<TBODY><TR><TD style="TEXT-ALIGN: center"><P style="TEXT-ALIGN: center; MARGIN-BOTTOM: 0px"><FONT size=2
face="Verdana, Arial, Helvetica, sans-serif">The e-mail address is
ag*****@ sk*****.com<BR><A style="COLOR: #0a86fa"
href="http:// counthas.com/">Unsubscribe from this e-mail</A> | <A
style="COLOR: #0a86fa" href="http:// counthas.com/">FAQ</A> | <A
style="COLOR: #0a86fa" href="http:// counthas.com/">Advertise</A> | <A
style="COLOR: #0a86fa" href="http:// counthas.com/">Privacy
Policy</A></FONT></P><P style="TEXT-ALIGN: center; MARGIN-BOTTOM: 0px"><FONT size=1
face="Verdana, Arial, Helvetica, sans-serif">Copyright 15686 Inc. All rights reserved.
</FONT></P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
</BODY>
</HTML>


Spam Images

The image in Figure 8 shows the finished product of all this effort, a spam email, as it is seen by the targeted recipient. A mouse click on the image or any of the text links, on purpose or by accident, will take the user to the online sales site. Notice that the links at the bottom that claim to lead to "Unsubscribe", "Privacy Policy" and so on, are fraudulent, and in fact just lead to the sales site.




Figure 8: Spam Email Created from the Template

Finally, here is the online sales site the user will be transported to. This rather notorious business provides the money that finances the Ozdok spam, and motivates the distribution of the malicious bot software. Prospective buyers would be well advised to look elsewhere for pharmaceutical bargains. The image in Figure 9 should be a familiar one, as this site (Canadian Pharmacy) has been around for quite some time - indicated in our analysis from 2008.




Figure 9: The Online Sales Site

Conclusions

The most interesting aspect of the Ozdok botnet is its continued success. Despite a few deficiencies and bugs, it does have some things working in its favour. One of these is the redundant STS servers and load balancing that maintain the spam flow rate even when most of the bots are online. Another is the DES message encryption, which makes IPS detection difficult. Persistant support seems to be an advantage, one bot variant continued to join the botnet, and send spam, ten weeks after its first appearance, meaning existing bots are not wasted. As we have seen the proper handling of network errors has not been neglected.

On the other hand there are some problems - the lack of a backup C&C for example. There also appears to be a software bug that limits the amount of spam that is sent. But in the end it seems that Ozdok does enough things right to survive.