Blog

A little more on Donbot…

Donbot
is primarily a spam bot, one of the few spam botnets whose growth was
not hampered by the McColo shutdown earlier this year.  As a matter of fact, the sudden
shut down of big spammers like Srizbi and Rustock helped Donbot climb the
spam botnet rankings.  In this article I am going discuss different aspects of Donbot, first as a malware and then in the
later half I will try to shed some light on its command and control architecture.

Lets start with a particular donbot sample (273a07dccdfff421bfde652912f02e32).  Like its peer botnets (Ozdok, Xarvester etc), Donbot is also a template based spam bot.  Everything from the subject line to the mailing list, the message body, and the User Agents to be used in the SMTP headers are retrieved from the CnC server. 

Template

Donbot does not use any standard protocol to communicate to its CnCs.  It uses a home grown plain text protocol instead.

Here is the a snippet of some protocol headers.

Cnc_proto

Donbot maintains sessions with its CnC server in a heart beat fashion by ending its tcp session after every request/response exchange.  A typical Donbot
packet exchange looks like this:

Request
(Greeting: Bot to Master ) 

Response
(Command: Master to Bot)

TCP
session end

Next
Request (Greeting: Bot to Master )                                                                                          

Next
Response (Command: Master to Bot)                                                                                         

TCP
session end

where the greeting message from bot  to master is nothing more than a constant string  'HALLO\r\n'.  Right after the greeting packet Donbot sends other information to the CnC in the following format:

Hash:
273a07dccdfff421bfde652912f02e32

ID:
msrx

Session:

Domain:
 

RBL:
0

Sent:
0

Failed:
0

Catchall:
0

Hash

is the MD5
hash of the malware binary image.
This would help bot masters decide if they need to update the bot binary to evade anti-virus detection. 

ID

is the name of
the executable image.

Session

is a 32 character session identifier. The CnC server assigns a session ID to each bot connecting to it.  In the first exchange the session field will be left empty. After first packet, session id will be used in all subsequent requests.

Domain

is the domain name of the CnC
server.  It is left empty if the bot is directly communicating using the IP
address of the server.

RBL

is a
very interesting field.  RBL is an acronym for “Real-time Blackhole List”.  It is
a list of hosts which have been flagged in the proliferation of spam.  It
currently points to dnsbl.njabl.org, where the RBL is maintained.  Why would a spambot need such information? There
could be several reasons. The most likely of them is to see if it has been
blacklisted itself.  If such a scenario occurs the bot could potentially “keep
it quiet” for a while to bring itself off the list.

After the initial two request packets, the server responds with whatever command it wants the bot to execute.  As shown in screen shot above, the command for updating the binary is “UPDATE|0d 0a|”. Here is the code snippet that will get executed on the UPDATE command.


.data:004093D8                 lea     eax, [ebp-418h]
.data:004093DD                 mov     dword ptr [esp+4], offset aUpdate ; "UPDATE"
.data:004093E5                 mov     [esp], eax
.data:004093E8                 call    sub_40A4A0
.data:004093ED                 test    eax, eax
.data:004093EF                 jnz     loc_409494
.data:004093F5                 call    sub_40A448
.data:004093FA                 mov     ebx, eax
.data:004093FC                 mov     dword ptr [esp], 0
.data:00409403                 call    sub_40A530
.data:00409408                 mov     [esp+0Ch], ebx
.data:0040940C                 mov     [esp+8], eax
.data:00409410                 mov     dword ptr [esp+4], offset aLuI_exe ; "%lu%i.exe"
.data:00409418                 mov     eax, [ebp+8]
.data:0040941B                 add     eax, 164h
.data:00409420                 mov     [esp], eax
.data:00409423                 call    sub_40A4D8
.data:00409428                 mov     dword ptr [esp+4], offset aWb ; "wb"
.data:00409430                 mov     eax, [ebp+8]
.data:00409433                 add     eax, 164h
.data:00409438                 mov     [esp], eax
.data:0040943B                 call    sub_40A4C8
.data:00409440                 mov     [ebp-83Ch], eax
.data:00409446                 cmp     dword ptr [ebp-83Ch], 0
.data:0040944D                 jz      short loc_409494
.data:0040944F                 mov     eax, [ebp-83Ch]
.data:00409455                 mov     [esp+0Ch], eax
.data:00409459                 mov     dword ptr [esp+8], 1
.data:00409461                 mov     eax, [ebp-81Ch]
.data:00409467                 mov     [esp+4], eax
.data:0040946B                 mov     eax, [ebp-820h]
.data:00409471                 mov     [esp], eax
.data:00409474                 call    sub_40A570
.d
ata:00409479                 mov     eax, [ebp-83Ch]

.data:0040947F                 mov     [esp], eax
.data:00409482                 call    sub_40A4A8
.data:00409487                 mov     eax, [ebp+8]
.data:0040948A                 mov     dword ptr [eax+160h], 1
 

Donbot will get a new spam template with the "chunk" command (CHUNK|0d 0a|). A typical chunk command
is shown below.


Chunk

Here is the complete list of commands/keywords that I picked up from the memory dump. Time doesn't permit me to discuss all this in a single post, I will go into details of each of them in some other post.

.data:0040C47E aOpen           db 'open',0             ; DATA XREF: .data:004083C0 o
.data:0040C483 aHallo          db 'HALLO',0Dh,0Ah,0    ; DATA XREF: .data:loc_408469 o
.data:0040C48B aHashS          db 'Hash: %s',0Dh,0Ah,0 ; DATA XREF: .data:0040848E o
.data:0040C496 aIdS            db 'ID: %s',0Dh,0Ah,0   ; DATA XREF: .data:004084B3 o
.data:0040C49F aSessionS       db 'Session: %s',0Dh,0Ah,0 ; DATA XREF: .data:004084D8 o
.data:0040C4AD aDomainS        db 'Domain: %s',0Dh,0Ah,0 ; DATA XREF: .data:00408500 o
.data:0040C4BA aRblLu          db 'RBL: %lu',0Dh,0Ah,0 ; DATA XREF: .data:00408528 o
.data:0040C4C5 aSentLu         db 'Sent: %lu',0Dh,0Ah,0 ; DATA XREF: .data:00408550 o
.data:0040C4D1 aFailedLu       db 'Failed: %lu',0Dh,0Ah,0 ; DATA XREF: .data:00408578 o
.data:0040C4DF aCatchallLu     db 'Catchall: %lu',0Dh,0Ah,0 ; DATA XREF: .data:004085A0 o
.data:0040C4EF aXSentS         db 'X-Sent: %s',0Dh,0Ah,0 ; DATA XREF: .data:004085F2 o
.data:0040C4FC aDebugS         db 'Debug: %s',0Dh,0Ah,0 ; DATA XREF: .data:00408652 o
.data:0040C508 asc_40C508      db 0Dh,0Ah,0            ; DATA XREF: .data:loc_408682 o
.data:0040C50B aSession        db 'Session: ',0        ; DATA XREF: .data:004087A6 o
.data:0040C515 aRand           db 'Rand: ',0           ; DATA XREF: .data:004087F0 o
.data:0040C51C aMaxTo          db 'Max-To: ',0         ; DATA XREF: .data:00408840 o
.data:0040C525 aMaxThreads     db 'Max-Threads: ',0    ; DATA XREF: .data:00408891 o
.data:0040C533 aIp             db 'IP: ',0             ; DATA XREF: .data:004088E2 o
.data:0040C538 aLength         db 'Length: ',0         ; DATA XREF: .data:0040897A o
.data:0040C541 aClearBuffers   db 'Clear Buffers',0    ; DATA XREF: .data:004089C0 o
.data:0040C54F aMacro          db 'Macro: ',0          ; DATA XREF: .data:00408B17 o
.data:0040C557 asc_40C557      db 0Ah,0                ; DATA XREF: .data:00408BCC o
.data:0040C559 aMessage        db 'Message: ',0        ; DATA XREF: .data:00408CF7 o
.data:0040C563 aDebug          db 'Debug: ',0          ; DATA XREF: .data:00408DE2 o
.data:0040C56B aSleep          db 'Sleep: ',0          ; DATA XREF: .data:00408E33 o
.data:0040C573 aPopup          db 'Popup: ',0          ; DATA XREF: .data:00408E81 o
.data:0040C57B aPopupTime      db 'Popup-Time: ',0     ; DATA XREF: .data:00408F03 o
.data:0040C588 aKeepAlive      db 'Keep-Alive: ',0     ; DATA XREF: .data:00408F54 o
.data:0040C595 aRbl            db 'RBL: ',0            ; DATA XREF: .data:00408FA5 o
.data:0040C59B aBlockcatchalls db 'BlockCatchalls: ',0 ; DATA XREF: .data:00408FF3 o
.data:0040C5AC aProxylock      db 'ProxyLock: ',0      ; DATA XREF: .data:00409044 o
.data:0040C5B8 aProxylocklist  db 'ProxyLockList: ',0  ; DATA XREF: .data:004090DC o
.data:0040C5C8 aChunk          db 'CHUNK',0            ; DATA XREF: .data:0040932A o
.data:0040C5CE aUpdate         db 'UPDATE',0         &#
0160; ; DATA XREF:

Most of the Donbot sample I recently analyzed had
the port and the CnC ip hard coded in the binary.  Although some older samples were also seen using a hard coded domain list.  I have also observed that Donbot does not have any fall-back mechanism.  If a CnC is taken out, samples communicating to that particular CnC
will be lost forever.  Bot herders push new samples to their zombies
every time they need to change the CnC hosts.

Here are some of the active command and control servers..

 CNC IP Address

ISP

Country

Region

City

98.126.16.170

VPLS INC. D/B/A
KRYPT TECHNOLOGIES

UNITED STATES

CALIFORNIA

ORANGE

67.43.158.234

EFFICIENT NET

UNITED STATES

CALIFORNIA

ORANGE

78.159.102.117

 

NETDIREKT E.K

GERMANY

BERLIN

BERLIN

89.149.242.124

NETDIREKT E.K

 

GERMANY

 

 

In the absence of a good fallback mechanism, quick action by these data centers could knock Donbot to its knees, making a considerable difference in world wide spam volume.

Note: Thanks to my colleague Atif Mushtaq for giving me some valuable tips for my first article.

Haroon W Malik @ FireEye Malware Intelligence Lab

Detailed Question/Comments : research SHIFT-2 fireeye DOT COM