Recently a weaponized MS Doc file was given to me for analysis. Due to the fact that an initial sandbox analysis detected that it contains an exploit, it raised my curiosity. So let’s see what we have.
Definitely suspicious! Especially this VirtualAlloc call seems quite interesting. Below you can find a screenshot of the extracted VBA code.
As you can see it is full of comments which could be easily removed with a Regular Expression on Notepad++ or Sublime etc. Between the comments there is actual code and junk code which has to be removed also. What caught my attention is the CallWindowProcA and RtlMoveMemory (red color). I have recently read a blog post about the CallWindowProc (http://waleedassar.blogspot.gr/2012/03/visual-basic-malware-part-1.html) that is being currently used by Macro malwares. What this function does, is to execute an allocated memory directly. This is a more direct method than using CreateProcess, ShellExecute, WriteMemory, Hollow Process techniques etc.
After cleaning the file we have the following code (snip)
The autorun function contains a call to cakewalk function which is the main function of the document. Inside cakewalk the following things take place:
- Volumetric stream is being called and object sashay is being referenced. We have seen at the output of oledump that there is a stream named volumetric (17). Due to the fact that I haven’t manage to programmaticaly extract such objects (e.g a python library) I prefer to use LibreOffice in order to access the various components. As you can see in the next screenshot volumetric is a UserForm and sashay is a label. The text of the label is the actual shellcode which will be decoded.
- The shellcode is passed for decryption/decoding in function methylated
- Then a memory allocation takes place (VirtualAlloc)
- Function heft is called which takes the current document’s full name (ThisDocument.FullName) (the code is not included in the previous screenshots)
- The allocated memory is filled by a function leuciscus.
- Finally the CallWindowProcA is being called in order to execute the decoded shellcode. Note that based on the architecture (32bit or 64bit) different offsets are being used. Also note that in the second argument called diduction is the file name of the current document. This is important and keep that in mind
So how do we dump the shellcode (From now on this shellcode will be called Stage1 Loader)? Just recreate the function methylated in a macro in an MS Word document, save it to a file and open it in IDA.
Now lets analyze the Stage1 Loader. The starting offset for 32 bit is 2214 (0x8a6).
So the offset is a function prologue, then we are correct! I will not explain in detail the assembly code because it will need too many screenshots, but the basic idea is the following:
- Go to PEB fs:30 and get the loaded DLLs linked list in order to find the second in list (ntdll.dll).
- There is a function SeachFunctionName which gets two arguments, a DLL address and a string of a function. It searches the respective function address and returns the value. Screenshot can be seen below with the internals of the function
- The function names that are being searched are the following:
- There is a function block that converts ascii to unicode in order to pass “kernel32.dll” as unicode argument to LdrLoadDll (LdrLoadDll( IN PWCHAR PathToFile OPTIONAL, IN ULONG Flags OPTIONAL, IN PUNICODE_STRING ModuleFileName, OUT PHANDLE ModuleHandle );). The function returns a handle to kernel32.dll. ExpandEnvironmentStringA is a kernel32.dll function all the order ones are ntdll.dll functions
- It tries to open the actual word file (in order words itself). Remember when I mention that you should keep in mind the second argument of CallWindowProcA? Here it is
The arg0 is the current document. Why does it use this approach? Let’s see on step 6.
- Then it reads the the word document itself until it finds the 0x504f4c41 byte sequence. This is important because the Stage1 Loader is just a loader not the actual malware. It seems that there is another secondary shellcode which is encoded/encrypted inside the Word document, while the Stage1 Loader is an embedded Macro Object. The specific byte sequence is the marker of the beginning of the secondary shellcode (Stage2 Loader).
- It then creates a file in %TMP%\oi809.exe, it decodes the code from the previous step and writes it to the oi809.exe.
- Finally it executes the oi809.exe
Some internals of the “SearchFunctionName”
Also the internals of the FindExportDirectoryRVA, with the various checks for the validity of the PE
If you want to make dynamic analysis of the Stage1 Loader you need a way to break the execution into it. You can use something like the following code. The Stage1 Loader is already dumped into a file (remember the replicated macro we created) and accessed by our code.
HANDLE hFile = CreateFileA(argv, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); DWORD dwFileSize = GetFileSize(hFile, NULL); DWORD dwReadData = 0; DWORD dwOldProtect = 0; LPVOID dataAlloc = VirtualAlloc(NULL, dwFileSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); LPBYTE target = (LPBYTE)dataAlloc + 2214; ReadFile(hFile, (LPBYTE)dataAlloc, dwFileSize, &amp;amp;amp;dwReadData, NULL); char* fff = &amp;quot;C:\\temp\\stage1loader.bin&amp;quot;; __asm int 3; CallWindowProc((LPBYTE)dataAlloc+2214, fff, 0, 0, 0);
A note, inside the internals of CallWindowProcA there is a call dword ptr[ebp+0x8]. The offset is different in each version of windows. If you can’t find the offset of the call instruction just add a 0xcc byte (int3) in the stage1loader.bin and let it break in the debugger. With manual stack walking you can get the return address which is the call dword ptr[ebp+0x8] instruction. With a debugger you can add a breakpoint there.
The oi809.exe analysis
To be honest I didn’t have the time to thoroughly analyze the file so I will only give a vague description of what is going on. This is the beginning of the oi809.exe. This particular executable is our Stage2 Loader.
As you can see there are some delay loops, probably for anti analysis (you can easily set edi value to 1). The most important functions (sorry for the chosen names) are the DecryptPayloadResource which is responsible for decrypting a resource inside the executable and the HollowProcess function which uses the classic technique that, executes it self again, unmaps the executable rewrites it with the needed code, uses SetThreadContext to set the starting point and then ResumeThread to continue execution.
The decryptPayloadResource searches for a resource of type RCDATA(0xA) and ID 0x821B (33307)
Then it tries to decrypt it
Finally lets have a look and the HollowProcess block which writes the decrypted shellcode in the memory of newly created process.
Nothing new about that. In order to dump the actual malicious content for further analysis you need to add a breakpoint in the debugger in 0x00401930 where the ebx register will contain the payload of size equals to eax value. From ollydbg you can easily dump it.
Uploading the dumped contents we get a suspicion that the actual malicious file might be Teslacrypt.
Unfortunately I have not analyzed the actual malware. I am sure (if it is Teslacrypt) the are plenty of excellent articles and analyses.
If you have reached this point I would like to thank you for your patience. In case something is wrong with the analysis or you have any suggestions please let me know.