Analysing a Multi Stager : A case study of QBOT


This is not going to be about QBOT analysis rather a quick \”how-to\” for analysing malwares that employ multiple stages in the infection chain. Recently, in my work, I got a sample (a mal pdf) for analysis, at the time I had no prior information and task was identification. Interestingly initial vector used to execute the sample involved iso images, JScript and VBS, finally I retrieved a DLL file that was saved on the disk as a txt file. After performing an in-depth analysis, I figured out that it was loading some other DLL and giving control to the DllEntry of the new DLL! hmmm interesting. I retrieved the new DLL and started working on it. I saw two interesting(unusual) strings \”C:\\INTERNAL\\__empty\” and \”SELF_TEST_1\”. I went ahead and googled the strings and found two reports one from Uptycs and other from Elastic about Qbot analysis. Both of these reports were telling the same story and I had the same findings only difference was I had no idea it was QBOT (first time seeing one lol)
Now that is the backstory, the motivation for this post is something else, QBot is just another malware in the wild that has multiple stages in its infection chain. Analysing Qbot made me think – How would one approach the issue of analysing a staging mechanism especially when the next stage happens inside a remote process which you are not debugging currently and resume the analysis process in the target process? Hence this post!

QBot infection : An overview

  • Qbot has three stages, first stage is initialisation, second stage is installation and final stage is for communication.
  • In the initial phase, it tries to inject itself into remote process through process hollowing vector. The malware will initiate its second stage from the remote process. The entry point function in the target process will be changed to second stage code in the malware.
  • Following are the binaries it uses to create the process to perform process hollowing.
    • C:\\Windows\\SysWOW64\\wermgr.exe
    • C:\\Windows\\SysWOW64\\msra.exe
    • C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe
  • The first thing that second stage does is to corrupt the malware binary on the disk used in first stage.

This information is enough for us to perform analysis of the second stage.

fun in jumping between procesesses

Before getting our hands dirty, I have to set some things straight.

  • Debugger A : Its the debugger that has the unpacked Qbot dll and this is stage-I
  • Debugger B : When stage-I creates target process in suspended state, we will attach a debugger to it for analysing stage-II.

I will go back and forth with these terms so don\’t get confused! Without further ado lets dive in !

get that context

  • Since we already have a clear picture of what we are up against (Process hollowing), first thing comes to my mind is the GetThreadContext and its role in process hollowing. The reasoning behind that is quite simple, malware needs to redirect the execution in the new process to its code hence the CONTEXT!
  • Our objective is very simple, find out about the new entry point in the process, so I know the way-out should be somewhere in the lines of code between GetThreadContext and ResumeThread.
  • Put a breakpoint on GetThreadContext function in debugger A. As shown in the image above, QBot calls the api to make the EIP of the thread in target process to point to malware code. The malware creates the target process in suspended state before breakpoint hits, this is shown in the image below, in our case the target process is \”wermgr.exe\”. (NO BRAINER 😉 )

let the malware write

  • Further debugging the code line by line in debugger A, one interesting api call is ZwWriteVirtualMemory as shown in the image above. There is one call prior to this one which is NtProtextVirtualMemory with memory protection constant of value 0x04 and target memory region is a memory location in target process OFCOURSE!
  • Arguments passed to ZwWriteVirtualMemory api are shown below. the second argument is BaseAddress where data in the buffer (third argument) is going to get written in.
  • This is where things get interesting and fun! Since this memory location is in completely different process, we need to fire up a new debug session.

new debug target

  • Start a new debugger session by attaching it to our target process (wermgr.exe), Now we have two active debuggers, one (A) is our initial loader and second one (B) is the target process used by the malware to initiate second stage.
  • In the debugger B, go to the BaseAddress used in ZwWriteVirtualMemory (loader process) seen in debugger A, in my case it is B954A0. As shown in the above image, the address points to EntryPoint of wermgr.exe.
  • Now this makes sense right? Ands we kind of know what it is trying to achieve here. Image below shows the legitimate EntryPoint of the wermgr.exe in debugger B.
  • After stepping over the ZwWriteVirtualMemory in debugger A, check the previous address (B954A0) in debugger B. The change made to the code by the malware is highlighted in the image below. call wemgr.B95995 is changed to jmp A16767.
  • This is the key to analyse the second stage of QBOT initiated from within hollowed wermgr.exe.
  • In debugger B, lets check our new EntryPoint (A16767);image shown below. We are inside the QBOT code used in second stage operation.
  • Doing a quick memorymap lookup in debugger B for the above address would not hurt! Ofcourse the RWX is good indicator of maliciousness and gives hope to the researcher lol.
  • The process hacker output for the same(wermgr.exe). So this where the QBOT initially injected itself and made the necessary changes in wermgr.exe to divert the execution to this RWX memory region. NICE!
  • Go back to debugger A, continue debugging the code, you will end up seeing a call to ResumeThread as shown below, step over it and go back to debugger B.

Now you can analyse the second stage of the QBOT, you are inside wermgr.exe and you have an active debug session. Make sure to take a snapshot of your VM, so you don\’t have to go through all this all over again when you mess up something. 🙂


ending note

  • We started analysing one process, which is our DllEntry of QBOT (Stage-I)
  • By understanding the malware code and vector used we retrieved new entrypoint.
  • Using new address of entry we pivoted to the new process. Now we can go forward and analyse the second stage.
  • This thinking and problem solving is not limited to QBOT but can be applied to any malware that employs multiple stages. Always get a complete picture of what you are up against in terms of code logic and vector.

Leave a Reply

Your email address will not be published. Required fields are marked *