ThreatFire protected systems have been preventing Urlzone (also known as Bebloh), which has been flying under the radar of most AV vendors, for most of the year. The family is long in the wild and a pernicious one, so why the lack of recognition? Let’s take a quick look at some complexities related to the unpacking stub and the file’s delivery.
Multiple variants of the family implement an unpacking stub that burns through anti-emulation time lock loops intermixed with additive decoding loops, and then transfer control to underlying layers of the unpacking code by making a service pack dependent calculation to the location that control must be transferred to.
All of these calculations are surrounded by garbage code, so let’s strip down the trick to its bare bones: calculations are made, edx is pushed on the stack and control is transferred to that location with a return instruction.
The correct value of edx is arrived at by subtracting a predictable data value copied from a location near the kernel32 module entrypoint to attain the expected value. Kernel32 changes across service packs, so uploading these samples to automation tools may produce varying results depending on whether or not the researcher downloading from the distribution web server indicated the same service pack in the http request on the client system as on the automation system.
So what data may change across service packs and protected OS’s? The data preceding and at the entrypoint of kernel32. The unpacking routine is dependent on finding the values in the Peb (Process Environment Block) for the “InLoadOrderModuleList”, which points to a list of loaded modules (dlls) within the process. This technique is often used in exploitation-delivered shellcode (see skape’s section 3.2.1 on using PEB to find kernel32). The unpacking stub then walks the list to find the pointer to the entry point of kernel32.
A predictable sequence of bytes exists prior to and at kernel32’s entrypoint per Service Pack. The calculation in the this post is meant for XP SP3, any SP prior causes the malware to calculate an incorrect location and exit. That predictable sequence also changes if the entrypoint of kernel32 is hooked. Any jmp instructions will break the control.
Hence, the 0×8b909090 value (the three nop bytes prior to kernel32.EP and the push ebp) for use in a sub from their hardcoded value to calculate the final jmp destination.
Following the sub from edx, ebx is discarded. Edx is pushed to the stack for a ret and the malicious execution continues from there…