Select Page

(Analysis by Chandra Prakash, Technical Fellow, GFI Labs )

Microsoft’s Windows operating system, running on a 64-bit machine provides enhanced security with driver signing of system and low level drivers. This policy, called the kernel mode code signing policy, disallows any unauthorized or malicious driver to be loaded. [1.]

 The TDL4 rootkit bypasses driver signing policy on 64-bit machines by changing the boot options of Microsoft boot programs that will allow an unsigned driver to load.

Here’s how it’s done:

The boot option is changed in memory from the code executed by infected MBR. The boot option configures value of a config setting named ‘LoadIntegrityCheckPolicy’ that determines the level of validation on boot programs. The rootkit changes this config setting value to a low level of validation that effectively allows loading of an unsigned malicious rootkit dll file. The rootkit dll is kdcom.dll, which is an infected version normal kdcom.dll that ships with Windows.

The rootkit also disables debuggers by NOP’ing debugger activation functions as described below. This makes reverse engineering this rookit very difficult! The KdDebuggerInitialize1 (see below) function in infected kdcom.dll called during normal execution of the system installs the rootkit, which hooks the IRP dispatch functions of miniport driver below the disk to hide its malicious MBR.

On a normal machine an unsigned driver will show this message

*** Windows is unable to verify the signature of
    the file Windowssystem32kdcom.dll.

 By changing the boot option, display of the above message is also suppressed.

(This was researched on a 64-bit machine with Windows 7 installed)

 Infected Kdcom.dll with debugger functions NOP’ed out

.text: public KdDebuggerInitialize0
.text: mov cs:byte_1800019EC, 3
.text: xor eax, eax
.text: retn <– Debugger function NOP’ed out that prevents debugger attachment

.text: public KdSendPacket
.text: mov     cs:byte_1800019EC, 6
.text: retn <– Debugger function NOP’ed out

.text: KdDebuggerInitialize1
.text: lea     rcx, sub_18000190C <– This function installs the rootkit
.text: jmp     cs:PsSetLoadImageNotifyRoutine
.text: public KdDebuggerInitialize1 endp

Corresponding functions of clean Kdcom.dll

 .text:  public KdDebuggerInitialize0
.text: mov     [rsp+arg_0], rbx
.text: mov     [rsp+arg_8], rsi
.text: push    rdi
.text: sub     rsp, 20h

(snip)

.text: public KdDebuggerInitialize1
.text: sub     rsp, 28h
.text: cmp     cs:KdComAddressID, 0
.text: jnz     short loc_7FF7045112A

(snip)

.text: public KdSendPacket
.text: mov     [rsp+arg_0], rbx
.text: mov     [rsp+arg_8], rbp
.text: mov     [rsp+arg_10], rsi
.text: push    rdi
.text: push    r12

(snip)

[REFERENCES]

[1.] Kernel-Mode Code Signing Policy (Windows Vista and Later),  http://msdn.microsoft.com/en-us/library/ff548231%28VS.85%29.aspx

Thanks Chandra.

Tom Kelchner