Analysing the Hancitor Maldoc
Recently we have seen several phishing attempts using macro enabled word attachments to load the Hancitor download trojan. The macros in these documents use routine windows API functions with a callback parameter in order to run shellcode directly in memory without the need to drop further files to disk. This entry follows the analysis of this method and may be useful for those new to the reverse engineering field.
This particular sample comes in the form of an OLE word document. Sandbox analysis or use of the python OLE tools from Didier Stevens will reveal that the document contains heavily obfuscated VBA macros including a Document_Open routine which will run as soon as macros are enabled for the document. The level of obfuscation means that the quickest way to reveal the actual function of the macros will be to run them in a controlled environment and follow the execution in Word's debugger.
Opening the Document and Accessing the Macro Code
On the version of Office I was using, it was not possible to open the document for editing without first trusting the content. This posed a problem as I did not want the macros to run until I had a chance to examine the code further and set some initial breakpoints. Even though I was using a clean Virtual Machine for the analysis I would rather avoid infection if at all possible.
In order to circumvent this it is first necessary to change the default Trust Centre settings within Word to allow all macros to run. Although this seems counter-intutive it means that by holding down the shift key whilst opening the document, either from the File-Open menu or by double clicking in Explorer, the document will open correctly but no macros will run. If you use this version of office for anything other than malware analysis then please ensure that you change the setting back once you have finished.
Once the document has been opened pressing Alt-F11 will transfer you to the Visual Basic for Applications (VBA) editor.
Stage 1 - Analysing the Macro Code
As we can see from the Project viewer in the window above the document contains three separate code containers:
- The Document Itself
- A separate module named presbyope
- A form named natal
Quickly clicking through reveals that both the document and the module contain heavily obfuscated code, while the windows form contains no code. The form itself is a single dialog containing a tab view and two tabs, but no buttons or menus or anything that would normaly perform events. Interestingly the first window that opens is the presbyope module and as we can see above this imports, and renames some interesting Windows API functions, including some interesting memory manipulation functions.
From experience we know that many malware samples use VirtualAllocEx in order to create a buffer which will later be used to execute shellcode or even full processes. In this case though the other process hollowing functions such as StartProcess, UnmapViewOfSection etc are not present so it looks like we will only be looking at the Word Process itself. Searching the code for calls to "madid" we find that there is only one.
Examining the code either side this can be viewed as:
ShellcodeBuffer = VirtualAllocEx(-1, 7386, 0x1000, 0x40)
A quick look at the MSDN documentation reveals that 0x1000 is equivalent to MEM_COMMIT and 0x40 to PAGE_EXECUTE_READWRITE, meaning that the buffer will be allocated on use and the memory pages will be marked as executable.
Widening our view further this call occurs within a function named "vasopressin", which also includes several calls to the function "bilaterally" which as we saw previously is actually the Windows API function RtlMoveMemory. Removing the junk code and renaming the variables renders this function as:
Dim PayLoadPtr As Long;
RtlMoveMemory PayloadPtr, ByVal VarPtr(PayloadString) + 8, 4;
Dim Result As Long;
NewBuffer = VirtualAllocEx(ByVal ProcessId, ByVal StartingAddress, 7386, 4096, 64);
RtlMoveMemory Result, ByVal VarPtr(NewBuffer) + 8, 4;
RtlMoveMemory ByVal Result, ByVal PayloadPtr, 5538;
vasopressin = Result;
Set MyTab = natal.libet.BoundValue("Tab2")
Length = 7368
LongString = Right(TipText, Length)
Payload = presbyope.satire(LongString)
#If VBA6 And Win64 Then
Dim PayloadPtr As LongPtr
Dim PayloadPtr As Long
PayloadPtr = Payload
ShellCodePtr = vasopressin(PayloadPtr)
#If VBA6 And Win64 Then
Offset = 1280
#ElseIf Win32 Then
Offset = 3677
Dim FunctionPtr As Long
FunctionPtr = ShellcodePtr + Offset
ThrowAway = EnumCalendarInfoW(FunctionPtr, 2048, 1, 1)
Checking the Microsoft documentation for EnumCalendarInfoW reveals that the first parameter is used to pass a callback function, which is used to process each information object as it is enumerated. If the function returns a 1 then EnumCalendarInfoW will pass it the next information object; if it returns a 0 then control will pass back to the original caller. Therefore as long as the shellcode exits with a 0 in the EAX register control will pass back to the macro and Word will continue to run normally. Other HANCITOR samples examined have used the EnumDateFormats and CallWindowProc API calls to achieve the same result.
By setting a breakpoint on the call to EnumCalendarInfoW we can see the value of the address being passed as shown here.