Today we will look at a Sample that uses Process Doppleganging to evade detection, Process Doppleganging is a pretty recent Injection Method that is not usually used alone, but mixed with other injection methods, most likely Process Hollowing, which is the case in this Sample.
Further read on Process Doppleganging, Process Hollowing and how Osiris Implemented a Hybrid of both worlds, Check the Malware Evasion Through Injection episode in The REM-Essentials Series.
Basic Threat Intel:
This Sample is of Agent Kroner Banking Trojan Family Osiris . The first stage involves injecting it's malicious payload into
→ Since This Sample use it's own copies of
ntdll.dll and other dlls to evade AV hooks, we would go through a different approach of debugging, rather that set breakpoints on known APIs that's involved in Process Doppleganging we would instead walk through the Code and check each function, this is going to be a long process but we'll end up following the Injection step by step.
Dynamically Unpacking the Sample:
From the Dynamic Execution Analysis we see the Sample spawns
wermgr.exe , So as a start we would set a breakpoint on CreateProcessInternalW and will debug through from there.
Once Running the Sample we hit the breakpoint with a path to
wermgr.exe and the process is spawned in a suspended state.
Following the Return from Step1 to User Code and Stepping through execution, we find calls to ZwQueryInformationProcess over the spawned
wermgr.exe by passing its hProcess 0x9c in my case, Continuing on we find a Function that takes NtCreateFile as a parameter, this could be performing some functions over a given hFile, Stepping into this function we find a call to another function that looks the same but this time with the path to
wermgr.exe that it might tries to open
wermgr.exe as a file[2`].
Stepping into this function, we see it constructs the path string to
wermgr.exe  and calls a NtAllocateVirtualMemory to allocate memory in it's own process[3`], on execution it returns a pointer to the allocated region of memory[3``].
Finally on Return a file of
wermgr.exe is created in the
Osiris.exe Process Memory.
Continuing On we find a Call to NtCreateSection with a hFile to the
wermgr.exe file that's been Created. So this Section will Contain the information inside the
wermgr.exe file. On Execution a Section is Created [4`].
Continuing On the Sample Tries to Map the Section into it's own Process Memory by calling NtMapViewOfSection over hSection, Returning a pointer to the Mapped Section that now Contains
Now that the Sample have a mapped copy of
wermgr.exe it calls ZwClose on both hSection and hFile (both of wermgr.exe) so we end up with the spawned
wermgr.exe that is still suspended and not altered and a mapped copy of it inside
Osiris.exe Process Memory.
Later On we find an interesting Function that takes hProcess of the remote
wermgr.exe as a parameter, Stepping into it, it calls NtQueryVirtualMemory over hProcess of
wermgr.exe couple of times, so we can assume it tries to figure out offsets of the legitimate binary[7`].
Now we come to the important part, where the Sample will create a file that does not really exist on disk, with which the legitimate
wermgr.exe will be injected in Memory.
This starts by an interesting function that is a wrapper to calls to NtCreateFile/NtAllocateVirtualMemory, This function construct the path string of the file to be created
\TEMP\\Liebert.bmp in this case, and returns a pointer to the allocated region of memory in it's own process[8`].
Next it Constructs a full path to the .bmp file.
The Sample still uses wrapper functions to implement low-level API calls, and by following through execution we find a call to NtCreateTransaction that returns a handle to a TmTx inside
// The existence of a TmTx Transaction is a clear indication of using Process Doppleganging/NTFS Transactions as an Evasion/Injection Technique to inject a payload in the Process Memory without ever getting caught on disk.
Leibert.bmp file is created.
The Sample uses another wrapper function that from it's parameters [ String to Leibert.bmp path, hTmTx, Base Address 0x300000, region of memory containing an Executable ] we can assume this will be the Write operation of the malicious payload[10`]. Stepping into the function we see the call to NtWriteFile of
// We would want to dump this out as it's still unmapped and easier to analyze.
Next the Sample Creates a Section Containing
Liebert.bmp data that's been written recently.
The Sample then will Rollback the TmTx Transaction to revert changes made to it by calling ZwRollbackTransaction, Closes the Transaction with calls to ZwClose. Now we're left with the newly created Section that Contains the Malicious Payload.
The Obvious Next Step is to Map that Section into the remote
wermgr.exe process, which is done by calling NtMapViewOfSection from hSection into hProcess at Base Address
// Dump this out and resolve the imports to start deeply analyzing the first stage injected payload.
Next is a Call to ZwProtectVirtualMemory to change the protection of the written binary, and couple of calls to NtWriteVirtualMemory for Process/Thread Parameters Setup and PEB entry point update and everything.
Next a Call to ZwResumeThread to execute the remote/injected
// The Dropper for Osiris used a couple of techniques that made it a very interesting Sample, Starting with making their own copy of NTDLL to escape the Security Products' hooks on important APIs, to using Process Doppleganging for writing a Malicious Payload into a Transaction with the illusion it's from a .bmp file, and lastly using Process Hollowing to inject the Malicious Payload into a suspended Legitimate Windows Binary.
:Now that's everything when it comes to using Process Doppleganging as part for dropping the first stage payload without getting caught on disk, this method is very stealthy and usually coupled with other Injection Method to make it even more stealthier.
Good Hunt!.. and later with another Sample. 👾👾