Sunday, December 16, 2012

#3 Disclosure of another 0day malware - Analysis of the final Payload (Part 3)

In the last Part of this series I partly analyzed the final Payload. I haven't finished the analysis of the malware due to lack of time (and interest), but I will provide as much as information I have discovered. It looks like this malware is a classic spying tool (information gathering), but it would be interesting to know who is the attacker and who are the victims. Unfortunately I don't have a chance to reveal the identity of both and speculation is also not possible since the lack of any hints.
The final Payload also wasn't uploaded to Virustotal, so the detection rates supposedly are very low.

Final Payload
Sample: netui.dll
Size: 37.376 Bytes
Timestamp: 09.06.2012 12:27:19
MD5: AA3E6AF90C144112A1AD0C19BDF873FF

We start by examing the Export functions of this .dll.


Init1

It sleeps for 10 seconds and waits for Main Thread to be finished (WaitForSingleObject()).

ServiceMain

This is the first time I see that IDA Pro 5.0 free correctly recognized the ServiceMain function with its structure!
At first the Service Control Handler is registered with help of RegisterServiceCtrlHandlerEx() function. The Service Handler checks for SERVICE_CONTROL_STOP, SERVICE_CONTROL_INTERROGATE or SERVICE_CONTROL_SHUTDOWN control codes and fills the elements of the SERVICE_STATUS structure with the appropriate values to call SetServiceStatus() function afterwards. Then a new Thread (Main Thread) is created and started by calling the CreateThread() function. There follows final calls to the SetServiceStatus() function.

DllMain

At first it builds the key for decrypting the strings, function names and library names which are later (also) used for dynamically resolving API addresses. Here is the full list of decrypted strings:

LoadLibraryA                                  
GetProcAddress                                
SetCurrentDirectoryW                          
Sleep                                         
KERNEL32.dll                                  
RegisterServiceCtrlHandlerExW                 
SetServiceStatus                              
ADVAPI32.dll                                  
PathRemoveFileSpecW                           
SHLWAPI.dll                                   
_except_handler3                              
_local_unwind2                                
MSVCRT.dll                                    
free                                          
_initterm                                     
malloc                                        
_adjust_fdiv                                  
netui.dll                                     
Init1                                         
ServiceMain                                   
nvgdata.dat                                   
nvsdata.dat
%s%S
SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer
IP
els.dll
rmdir /S /Q "%s"
systeminfo
Software\Microsoft\Internet Account Manager\Accounts\00000001
%.8d
%s%s                                  
%s is %s\n                                    
REMOVABLE                                     
FIXED                                         
REMOTE                                        
CDROM                                         
OTHER                                         
sptr
qfa
mpk                                        
/~%s/cgi-bin/%s.cgi?%s                        
Microsoft Enhanced Cryptographic Provider v1.0
POST
Domain...
Generic..
Server..
Share....
......
--%S                                       
Init                                          
UnInit
%s ID:%d Path:
COMSPEC
tmp.dat
 /c %s > \"%s\"
pstorec.dll                                   
PStoreCreateInstance
Name = %s
Internet Explorer
http
StringIndex
Data =
HKLM
HKCU
HKCC
HKCR
HKU
--%s--                       
Name: %s Type:
STRING Value:%s
DWORD Value:%.8x
BINARY Value:               
brvc                                          
MSIE 8.0
svchost.exe                                   
RSA1                                          
kernel32.dll                                  
GetLocalTime                                  
HeapDestroy                                   
DeleteCriticalSection                         
WaitForSingleObject                           
InitializeCriticalSection                     
HeapCreate                                    
SetErrorMode                                  
HeapFree                                      
HeapAlloc                                     
lstrlenA                                      
CloseHandle                                   
WriteFile                                     
SetFileTime                                   
CreateFileW                                   
GetLastError                                  
DeleteFileW                                   
lstrcatW                                      
HeapReAlloc                                   
ReadFile                                      
GetFileSize                                   
FindClose                                     
FindNextFileW                                 
HeapSize                                      
CreateEventA                                  
SetEvent                                      
InternetOpenA                                 
FileTimeToSystemTime                          
FindFirstFileW                                
PathIsDirectoryW                              
GetSystemTimeAsFileTime                       
GetFileTime                                   
SetFilePointer                                
GetDriveTypeA                                 
GetLogicalDriveStringsA                          
SetEndOfFile                                  
Sleep                                         
LeaveCriticalSection                          
EnterCriticalSection                          
ReleaseMutex                                  
CreateThread                                  
CreateMutexA                                  
MultiByteToWideChar                           
WideCharToMultiByte                           
GetModuleHandleA                              
TerminateThread                               
WaitForMultipleObjects                        
GetKeyNameTextW                               
SystemTimeToFileTime                          
GetModuleFileNameExW                          
GetSystemDirectoryW                           
FreeLibrary                                   
GetExitCodeThread                             
psapi.dll                                     
CreateToolhelp32Snapshot                      
CreateProcessW                                
TerminateProcess                              
OpenProcess                                   
lstrcmpW                                      
lstrlenW                                      
advapi32.dll                                  
RegSetValueExW                                
RegQueryValueExW                              
RegOpenKeyExW                                 
RegCloseKey                                   
shlwapi.dll                                   
RegEnumKeyExW                                 
RegEnumValueW                                 
RegQueryInfoKeyW                              
RegDeleteValueW                               
mpr.dll                                       
WNetCloseEnum                                 
WNetEnumResourceW                             
WNetOpenEnumW                                 
msvcrt.dll                                    
memset                                        
memcpy                                        
wininet.dll                                   
InternetConnectA                              
StrToIntA                                     
StrToIntW                                     
StrStrIW                                      
_snwprintf                                    
wsock32.dll                                   
gethostbyname                                 
inet_ntoa                                     
WSAStartup                                    
WSACleanup                                    
user32.dll                                    
SetForegroundWindow                           
GetForegroundWindow                           
CallNextHookEx                                
StrStrA                                       
GetKeyboardState                              
GetWindowTextW                                
UnhookWindowsHookEx                           
SetWindowsHookExA                             
DispatchMessageA                              
TranslateMessage                              
GetMessageA                                   
Process32NextW                                
Process32FirstW                               
GetTempPathW                                  
VirtualProtect                                
ToUnicodeEx                                   
ole32.dll                                     
CoInitialize                                  
CoUninitialize                                
CoTaskMemFree                                 
HttpSendRequestA                              
HttpSendRequestExA                            
InternetGetConnectedState                     
InternetCloseHandle                           
HttpOpenRequestA                              
InternetWriteFile                             
InternetQueryDataAvailable                    
_snprintf                                     
TryEnterCriticalSection                       
GetCurrentThreadId                            
GetEnvironmentVariableW                       
GetWindowThreadProcessId                      
GetKeyboardLayout                             
AttachThreadInput                             
PostThreadMessageA                            
PathFindFileNameW                             
crypt32.dll                                   
CryptStringToBinaryA                          
CryptBinaryToStringA                          
HttpEndRequestA                               
InternetReadFile                              
CryptReleaseContext                           
CryptDestroyKey                               
CryptEncrypt                                  
CryptGetKeyParam                              
CryptExportKey                                
CryptGenKey                                   
CryptImportKey                                
CryptAcquireContextA                          
GetModuleFileNameW
NetUI
{
}                      

Then some function addresses are resolved and stored into global variables. What's different to the other files is that the final Payload makes use of an Anti-Reversing technique by storing the vast majority of the function addresses in Heap memory. This way a reverser only sees the base pointer (eax/ecx in this case) and an offset into the Buffer that contains the addresses (see full list in Appendix), e.g.:

call dword ptr [eax+20h] -> CreateFile()
or
call dword ptr [ecx+0BCh] -> WNetEnumResourceW()

Then it checks if the final Payload (.dll) was loaded into the virtual address space of the current process (checks if "fwdReason" = "DLL_PROCESS_ATTACH [1]") and exits if not. Next it resolves a bunch of API addresses and exits if one function address can't be resolved without doing anything malicious. It then retrieves the module file name (GetModuleFileNameW()) and tests if it is "svchost.exe". If the final Payload wasn't installed as a Service (check Part 2 -> Registry "SharedTaskScheduler" or "Run" startup methods) the module name is either "rundll32.exe" or "Explorer.exe". Dlls which are present in the SharedTaskScheduler registry key are loaded by Explorer.exe at system startup. If the module name isn't svchost.exe, the malware knows that it had to create the Main Thread (CreateThread()), otherwise the Main Thread is created in the ServiceMain routine.

Main Thread
The Main Threads starts with the same anti (AV) emulation technqiue as we have seen before by using a set of MMX instructions. If the instructions aren't emulated the occuring exception is catched and the malware exits. There follows a function which resolves the majority of the Windows API function addresses for later use. If just one of these functions can't be resolved the malware also exits.

Figure 1: API function address resolving (if just one fails, the rest is skipped)

Next the module file name is retrieved by calling GetModuleFileName() function and cut to the next directory by using PathRemoveFileSpec() function. This new path ("C:\Windows\System32" or "C:\Documents and Settings\<Username>\Local Settings\Application Data") is set as the current directory with help of SetCurrentDirectory() function. Then the process is set to handle specified types of serious errors, so the system does not display the critical-error-handler message box. This is done to prevent any suspicious error messages done accidently by the malware.
In the following function the temporary folder is retrieved to build the strings "C:\Documents and Settings\<Username>\Local Settings\Temp\nvgdata.dat" and "C:\Documents and Settings\<Username>\Local Settings\Temp\nvsdata.dat" (Note: The temporary path can differ, see Part 2). There follows once again the retrival of the "els.dll" file time, or if this fails the system time. Then it opens the "HKEY_LOCAL_MACHINE" registry root key that was created by the 3rd Dropper (see Part 2) to get the encrypted data (RegOpenKeyEx() + RegQueryValueEx()). If that fails it tries to get the encrypted data from the "HKEY_CURRENT_USER" root key that was also created by the 3rd Dropper for that reason.

Figure 2: Retrieving of the encrypted registry data stored by the 3rd Dropper (see Part 2)

Next, the 9 strings from "IP" entry are decrypted in memory with the same function that was used for strings, functions names and library names at the beginning.

Then it checks if the last of the 9 strings is a "1" or "0" (see Part 2). If it is a "1" (as in our case), a new Thread with a Keylogger is created. As a keylogger, the "SetWindowsHookEx" method with type "WH_KEYBOARD_LL" is used (Google: "Keylogger SetWindowsHookEx"). First it checks if a key was pressed (WM_KEYDOWN, WM_SYSKEYDOWN) and then gets the window of the key message by using GetForegroundWindow() function.

Figure 4: Malware checks if a key was pressed

Next it gets the process name of the window in which the key was pressed (GetWindowThreadProcessId(), OpenProcess() + GetModuleFileNameEx()) and stores in into a buffer with some additional characters to better distinguish from the rest("-", "[", "]"). Thereafter the window text/capture is retrieved and also stored into the buffer (GetWindowText()) again with some characters ("[" and "]"). There follows the translation of the virtual key pressed into the actual key character (GetKeyNameText(), GetKeyboardState(), GetKeyboardLayout() + ToUnicodeEx()). After translation the character is also appended to the data in the buffer. Special pressed keys (Control, Tab, ...) are stored between the characters "{" and "}". The stored information in the buffer has the following form:

--[ModuleFileName]--
[WindowText]

...keyloggedCharacters...{CTRL}{ALT}....\n\n


After the receiving of the pressed key, the function CallNextHookEx() is used to continue. This function is also called if the message hasn't the type "WH_KEYBOARD_LL" to pass the hook information to the next hook procedure, otherwise it would be lost and that would be suspicious.

That's all of the code of this final Payload I have analyzed. Below I give you some additional information I stumbled across during analysis, but doesn't had the time to sequence.

I hope you enjoyed this 3 Part series of dissecting a multi stage malware. The completion of the analysis of this final Payload is left to the reader. ;-)


Final random Parts

As I have said, here are some random information of the final Payload:

- The final Payload is multithreaded (8 CreateThread() function calls) and uses InitializeCriticalSection(), EnterCriticalSection(), TryEnterCriticalSection(), LeaveCriticalSection(), DeleteCriticalSection() functions for data access synchronization
- It makes use of the Microsoft CryptoAPI (CryptAcquireContext(), CryptImportKey(), CryptGenKey(), CryptExportKey(), CryptGetKeyParam(), CryptEncrypt(), ...) to encrypt data with the RSA public-key encryption and then store it on disk (CreatFile() + ReadFile())
- Just like the Downloader, it also uses the Common Gateway Interface to transfer encrypted data (the gathered information, ...) to a Server (200.74.244.118), this time with the URL ".../~bing/cgi-bin/..."
- By using the GetDriveType() and GetLogicalDriveStrings() functions it retrieves the drive types (CDROM, REMOTE, FIXED, ...) and its appropriate drive names
- ...


Appendix

Windows API function offsets:

Hex    Function
0      InternetOpen
4     DeleteCriticalSection
8      WaitForSingleObject
C     InitializeCriticalSection
10    lstrlen
14    CloseHandle
18    WriteFile
1C    SetFileTime
20    CreateFile
24    GetLastError
28    DeleteFile
2C    lstrcat
30    HeapReAlloc
34    ReadFile
38    GetFileSize
3C    FindClose
40    FindNextFileW
44    HeapSize
48    GetLocalTime
4C    FileTimeToSystemTime
50    FindFirstFileW
54    CreateEvent
58    GetSystemTimeAsFileTime
5C    GetFileTime
60    SetFilePointer
64    SetEndOfFile
68    Sleep
6C    LeaveCriticalSection
70    EnterCriticalSection
74    ReleaseMutex
78    CreateThread
7C    CreateMutex
80    MultiByteToWideChar
84    WideCharToMultiByte
88    SetEvent
8C    TerminateThread
90    FreeLibrary
94    lstrcmp
98    lstrlen
9C    RegSetValueEx
A0    RegQueryValueEx
A4    RegOpenKeyEx
A8    RegCloseKey
AC    RegEnumKeyExW
B0    RegEnumValueW
B4    RegQueryInfoKeyW
B8    WNetCloseEnum
BC    WNetEnumResourceW
C0    WNetOpenEnumW
C4    CryptStringToBinary
C8    memset
CC    memcpy
D0    InternetConnect
D4    HttpSendRequest
D8    HttpSendRequestEx
DC    StrToIntA
E0    TryEnterCriticalSection
E4    StrStr
E8    StrStrI
EC    _snprintf
F0    _snwprintf
F4    inet_ntoa
F8    gethostbyname
FC    SetForegroundWindow
100    GetForegroundWindow
104    CallNextHookEx
108    ToUnicodeEx
10C    GetKeyboardState
110    GetWindowText
114    OpenProcess
118    InternetGetConnectedState
11C    InternetCloseHandle
120    HttpOpenRequest
124    InternetWriteFile
128    InternetQueryDataAvailable
12C    HttpEndRequest
130    InternetReadFile
134    CryptReleaseContext
138    CryptDestroyKey
13C    WaitForMultipleObjects
140    GetKeyNameText
144    GetModuleFileNameEx
148    GetTempPath
14C    StrToIntW
150    GetCurrentThreadId
154    GetWindowThreadProcessId
158    GetKeyboardLayout
15C    AttachThreadInput
160    PathFindFileName
164    CryptBinaryToString
168    CryptEncrypt
16C    CryptGetKeyParam
170    CryptExportKey
174    CryptGenKey
178    CryptImportKey
17C    CryptAcquireContext

No comments:

Post a Comment