Phase Bot – A Fileless Rootkit (Part 1)
The first thing you notice when opening it up in IDA is that the AddressOfEntryPoint is 0, this may seem like an error, but it actually isn’t. Setting the entry point to 0 means the start of the DOS header is used as the entry point, this is possible because most of the fields following the MZ signature aren’t required, and the M (0x4D) Z (0x5A) are actually valid instructions (dec ebp and pop edx respectively). I’m not sure the actual purpose of this trick, but it’s interesting nonetheless.
|Cancels out the MZ instructions then jumps to real entry point.|
The real entry point is contained within the first 560 bytes of the only section in the executable, this code is designed to get data stored within the non-essential NT header fields and use it to RC4 decrypt the rest of the section, which contains the 2nd stage (shellcode).
Most initialization happens is what appears to be the world longest function; the executable doesn’t have an import table so functions are resolved by hash. All the initialized data such as offsets, strings, and function addresses is stored within a large structure which is passed to all functions.
|but does anyone truly know what loops are?|
Once initialization is done the bot then check that PowerShell and version 2 of the .net framework is installed: if it is, normal installation continues, if not, it writes the bot code to a file in the startup folder.
For the bot to start with the system, a subkey named “Windows Host Process (RunDll)” is created under “hkcusoftwaremicrosoftwindowscurrentVersionrun”, with the following value:
The final stage, which runs from within PowerShell hooks the following functions by overwriting the first instruction with 0xF4 (HLT).
- ntdll!NtResumeThread (Inject new processes)
- ntdll!NtReadVirtualMemory (Hide malware’s memory)
- ntdll!NtQueryDirectoryFile (Hide file, only if failed fileless installation)
- ws2_32!send (Data stealer)
- wininet!HttpSendRequest (Internet Explorer formgrabber)
- nss3!PR_Write (Firefox formgrabber)
The HLT instruction is a privileged instruction which cannot be executed from ring 3, as a result it generates an 0xC0000096 Privileged Instruction exception, which the bot picks up and handles using a vectored exception handler. This is the same as standard software breakpoint hooking, but using an invalid instruction instead of int 3.
As you can imagine, the executable shows all sorts of malicious signs.
|NULL AddressOfEntryPoint, missing all data directories, invalid section name.|
It should be noted that some of the features advertised appear to be missing and the comments in the PowerShell code suggest that this sample is an early/testing version. I’ll update if I can get hold of a newer version.