Today I will go through two of the last rootkit packers I analyzed recently.
The first is a TDL3 rootkit (654f4a3d02f7cc4b0442a5fee44419d948fa0048) 1/40 on VT (as of 12 Oct) which is consistent with the recent timestamp.
From a first analysis it shows some weird characteristics:
1. contains multiple resources (which is weird for drivers, if you exclude the version info), one in particular ARCHIVE looks very suspicious
2. exports two functions: _CreateCompressedBuffer@0 and _WriteCompressedBuffer@4
3. tries to spoof a legit VMWare driver
Looking at the code confirms that something is not quite right
the presence of fake APIs, so common now in usermode packers, also in kernel packers is new (to me). The code itself is simple to follow and doesn’t employ any obfuscation, the resource we spotted before (ARCHIVE), which contains part of the original driver, is loaded, decrypted and mapped.
Few things to note is that the bulk of the original driver (contained in the resource data) is prefixed by 1000h bytes, taken from the start of the .PAGE section, before the decryption takes place (also the first 100h 0s of the resource are discarded). Splitting the original packed executable into multiple chunks that are glued together in memory is a common technique.
Also the decryption stage is somewhat characteristic: instead of modifying the bytes, they’re just shuffled, and in this phase the bytes are reordered to reconstruct the original form, this approach has the benefit of preserving the statistical properties of the data (i.e. no peeks in entropy).
The second one (cc700b59d1e2b8251484798903d538a2e87f9799) is more complex and also has a low detection 2/41 (15 Oct), it starts with a nice anti-emulation trick
.text:10002BE5 push ebp .text:10002BE6 mov ebp, esp .text:10002BE8 push cs // CS = 8h .text:10002BE9 call sub_10002C02 .text:10002BEE retn sub_10002C02: [...] .text:10002C05 mov eax, [ebp+arg_0] .text:10002C08 and eax, 3 ; .text:10002C0B add dword ptr [eax+ebp+4], 1 // increments ret address
as you can see the control flow is redirected to correct function (starting at 10002BEF) only if the value of eax at 10002C0B is 0, which happens when CS is 8h (as should be in kernel mode) but fails if for some reason you have 1bh like in usermode, so emulators should set this register properly.
After this initial check it’s pretty much like most of the packers out there, decrypts and transfers control to a chunk of code which performs the bulk of unpacking: loads the original binary decompress it with aplib, decrypts and then maps into memory (for those that are interested here the python script to resolve imports by hash, for those that don’t have better means to do the same ;) ).
the hidden treasure at the end of the unpacking is a spambot totally implemented in kernel, plus basic rootkit functionalities (hiding files), looking on google for the IP (currently down) and /blog/candy.php points to some malware samples widely detected, just not the kernel version :)
In conclusion driver packers are not yet comparable to their usermode cousins but for sure we can expect in the future an increase in complexity and porting of anti-debugging techniques also to kernelmode.