當一個進程被保護的時候 比如無法獲取其進程句柄權限 (openprocess) 或者無法獲取內存讀寫訪問權限的時候,則可以使用此方法來進行提權。
前置知識,了解windows系統句柄表的構成。
可查看本博客鏈接:
x64windows內核句柄表PspCidTable原理與解析 – iBinary – 博客園 (cnblogs.com)
1.2 原理
句柄表項結構 HANDLE_TABLE_ENTRY 里面有一個成員記錄了 當前句柄所需要得訪問權限。
結構如下:
代碼語言:JavaScript代碼運行次數:0運行復制
//0x8 bytes (sizeof)union _HANDLE_TABLE_ENTRY{ volatile LONG VolatileLowValue; //0x0 LONG LowValue; //0x0 struct { struct _HANDLE_TABLE_ENTRY_INFO* volatile InfoTable; //0x0 LONG HighValue; //0x4 union _HANDLE_TABLE_ENTRY* NextFreeHandleEntry; //0x4 struct _EXHANDLE LeafHandleValue; //0x4 }; ULONG Unlocked:1; //0x0 ULONG Attributes:2; //0x0 struct { ULONG ObjectPointerBits:29; //0x0 LONG RefCountField; //0x4 ULONG GrantedAccessBits:25; //0x4 ULONG ProtectFromClose:1; //0x4 ULONG NoRightsUpgrade:1; //0x4 }; ULONG RefCnt:5; //0x4};
其中他大部分是聯合體組成,其核心字段則是 GrantedAccessBits
所以我們的做法是 首先拿到被降權的句柄,然后將此句柄的 權限修改為
完整權限,也就是 0x1fffff 。修改完成之后再用提權的句柄進行我們的操作。
二丶代碼演示2.1 核心提權驅動代碼
核心驅動代碼很簡單。
如下:
代碼語言:javascript代碼運行次數:0運行復制
#include <ntifs.h>#include <ntddk.h>typedef union _EXHANDLE{ struct { int TagBits : 2; int Index : 30; } u; void* GenericHandleOverlay; ULONG_PTR Value;} EXHANDLE, *PEXHANDLE;typedef struct _HANDLE_TABLE_ENTRY // Size=16{ union { ULONG_PTR VolatileLowValue; // Size=8 Offset=0 ULONG_PTR LowValue; // Size=8 Offset=0 struct _HANDLE_TABLE_ENTRY_INFO* InfoTable; // Size=8 Offset=0 struct { ULONG_PTR Unlocked : 1; // Size=8 Offset=0 BitOffset=0 BitCount=1 ULONG_PTR RefCnt : 16; // Size=8 Offset=0 BitOffset=1 BitCount=16 ULONG_PTR Attributes : 3; // Size=8 Offset=0 BitOffset=17 BitCount=3 ULONG_PTR ObjectPointerBits : 44; // Size=8 Offset=0 BitOffset=20 BitCount=44 }; }; union { ULONG_PTR HighValue; // Size=8 Offset=8 struct _HANDLE_TABLE_ENTRY* NextFreeHandleEntry; // Size=8 Offset=8 union _EXHANDLE LeafHandleValue; // Size=8 Offset=8 struct { ULONG GrantedAccessBits : 25; // Size=4 Offset=8 BitOffset=0 BitCount=25 ULONG NoRightsUpgrade : 1; // Size=4 Offset=8 BitOffset=25 BitCount=1 ULONG Spare : 6; // Size=4 Offset=8 BitOffset=26 BitCount=6 }; }; ULONG TypeInfo; // Size=4 Offset=12} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;typedef struct _HANDLE_TABLE{ ULONG NextHandleNeedingPool; long ExtrainfoPages; LONG_PTR TableCode; PEPROCESS QuotaProcess; LIST_ENTRY HandleTableList; ULONG UniqueProcessId; ULONG Flags; EX_PUSH_LOCK HandleContentionEvent; EX_PUSH_LOCK HandleTableLock; // More fields here...} HANDLE_TABLE, *PHANDLE_TABLE;typedef BOOLEAN(*EX_ENUMERATE_HANDLE_ROUTINE)( IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID EnumParameter );#ifdef __cplusplusextern "C"{#endif BOOLEAN NTAPI ExEnumHandleTable( IN PHANDLE_TABLE HandleTable, IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure, IN PVOID EnumParameter, OUT PHANDLE Handle); VOID FASTCALL ExfUnblockPushLock( IN OUT PEX_PUSH_LOCK PushLock, IN OUT PVOID WaitBlock );#ifdef __cplusplus}#endiftypedef struct _HANDLE_INFO{ unsigned long process_id; unsigned long access; unsigned long long handle;}HANDLE_INFO, *PHANDLE_INFO;unsigned char callback( PHANDLE_TABLE pHandleTableAddress, PHANDLE_TABLE_ENTRY pHandleTableEntryInfo, HANDLE Handle, PVOID pContext){#define ExpIsValidObjectEntry(Entry) ( (Entry) && (Entry->LowValue != 0) && (Entry->HighValue != -2) ) unsigned char result = 0; if (MmIsAddressValid(pContext)) { PHANDLE_INFO info = (PHANDLE_INFO)pContext; if (info->handle == (unsigned long long)Handle && MmIsAddressValid(pHandleTableEntryInfo) && ExpIsValidObjectEntry(pHandleTableEntryInfo) && pHandleTableEntryInfo->GrantedAccessBits != info->access) { pHandleTableEntryInfo->GrantedAccessBits = info->access; result = 1; } } if (pHandleTableEntryInfo) _InterlockedExchangeAdd8((char*)&pHandleTableEntryInfo->VolatileLowValue, 1); if (pHandleTableAddress && pHandleTableAddress->HandleContentionEvent) ExfUnblockPushLock(&pHandleTableAddress->HandleContentionEvent, NULL); return result;}void handleUpdateAccess(HANDLE_INFO info){ PEPROCESS process{ 0 }; NTSTATUS status = PsLookupProcessByProcessId((HANDLE)info.process_id, &process); if (NT_SUCCESS(status)) { //dt _EPROCESS find ObjectTable offset replace ox418 of offset PHANDLE_TABLE table_ptr = *(PHANDLE_TABLE*)((PUCHAR)process + 0x418); if (MmIsAddressValid(table_ptr)) ExEnumHandleTable(table_ptr, &callback, &info, NULL); ObDereferenceObject(process); }}VOID DriverUnload(PDRIVER_OBJECT){}EXTERN_CNTSTATUSDriverEntry( PDRIVER_OBJECT driver, PUNICODE_STRING){ driver->DriverUnload = DriverUnload; HANDLE_INFO info{ 0 }; info.process_id = 6288; //需要被提權的進程PID info.access = 0x1fffff; //設置為所有權限 info.handle = 0xA4; //提權進程拿到權限的句柄 handleUpdateAccess(info); return STATUS_SUCCESS;}
2.2 用戶程序以及使用說明例子
用戶層面演示例子:
代碼語言:javascript代碼運行次數:0運行復制
// ShutDownProtectProcess.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。//#include <windows.h>#include <iostream>using namespace std;int main(){ //可以拿到一個較低等級的權限 例如:PROCESS_QUERY_INFORMATION HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, 7652); BOOL bRet = FALSE; cout << "HANDLE = " << hex << hProcess << endl; cout << "Start Terminate Process " << endl; bRet = TerminateProcess(hProcess,0); if (bRet == FALSE) { cout << "TerminateProcess Error try two Terminate" << endl; system("pause"); //等待安裝好內核文件,來進行權限提升,在按任意鍵繼續 bRet = TerminateProcess(hProcess, 0); if (bRet == FALSE) { cout << "Two TerminateProcess Error " << endl; system("pause"); return 0; } { cout << "Two TerminateProcess Success " << endl; system("pause"); return 0; } } else { cout << "one TerminateProcess Success " << endl; system("pause"); return 0; } system("pause"); return 0;}
因為我沒有封裝內核通信。所以運行USER程序之后會等待用戶自己手動安裝驅動。
驅動里面的PID要改成USER程序的,也要把用戶獲取的HANDLE打印出來修改到驅動中。
然后重新編譯驅動,進行安裝。 安裝之后句柄就會被提權的。 此時用戶程序繼續運行即可結束被保護的notepad程序。
2.3 進程保護驅動Demo源碼代碼語言:javascript代碼運行次數:0運行復制
#include <ntifs.h>#include <ntstrsafe.h>#define PROCESS_TERMINATE (0x0001) // winnt#define PROCESS_CREATE_THREAD (0x0002) // winnt#define PROCESS_SET_SESSIONID (0x0004) // winnt#define PROCESS_VM_OPERATION (0x0008) // winnt#define PROCESS_VM_READ (0x0010) // winnt#define PROCESS_VM_WRITE (0x0020) // winnt// begin_ntddk begin_wdm begin_ntifs#define PROCESS_DUP_HANDLE (0x0040) // winnt// end_ntddk end_wdm end_ntifs#define PROCESS_CREATE_PROCESS (0x0080) // winnt#define PROCESS_SET_QUOTA (0x0100) // winnt#define PROCESS_SET_INFORMATION (0x0200) // winnt#define PROCESS_QUERY_INFORMATION (0x0400) // winnt#define PROCESS_SET_PORT (0x0800)#define PROCESS_SUSPEND_RESUME (0x0800) // winntPVOID g_ObjHandle;extern "C" NTKERNELAPIUCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);OB_PREOP_CALLBACK_STATUS MyObjectCallBack( PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation){ UNREFERENCED_PARAMETER(RegistrationContext); PEPROCESS pProcess = NULL; CHAR *pszName = NULL; pProcess = (PEPROCESS)OperationInformation->Object; pszName = (CHAR*)PsGetProcessImageFileName(pProcess); //判斷標志是否要打開進程 if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) { //獲取名字匹配 if (strstr(pszName, (CHAR*)"notepad")) { KdPrint(("%s rn", pszName)); //判斷是不是結束 if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE) == 1) { //如果是我們的.則設置DesiredAccess權限.去掉結束權限. OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (ULONG)~PROCESS_TERMINATE; return OB_PREOP_SUCCESS; } } } return OB_PREOP_SUCCESS;}VOID InitHook(){ //進行HOOK 回調鉤子寫法. OB_OPERATION_REGISTRATION oper; //你的回調函數以及類型都放在這個結構體中,可以是結構體數組. OB_CALLBACK_REGISTRATION CallbackRegistration; CallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION; //版本號 CallbackRegistration.OperationRegistrationCount = 1;//下幾個鉤子,也就是結構體數組個數 RtlUnicodeStringInit(&CallbackRegistration.Altitude, L"600000");//給個UNICODEstring表明您是干啥的 CallbackRegistration.RegistrationContext = NULL; //當你的回調函數到的時候參數是什么.由這里給出 CallbackRegistration.OperationRegistration = &oper; //鉤子結構體類型設置. //為鉤子結構體賦值 oper.ObjectType = PsProcessType; //進程操作的類型.當進程操作回來. PsThreadType則是線程操作 oper.Operations = OB_OPERATION_HANDLE_CREATE; //操作的類型是將要打開.以及將要重復 oper.PreOperation = MyObjectCallBack; //有兩個指針,前指針跟后指針.意思分別是 進程創建之前通知你還是之后 oper.PostOperation = NULL; ObRegisterCallbacks(&CallbackRegistration, &g_ObjHandle);}VOID UnHook(){ ObUnRegisterCallbacks(g_ObjHandle);}VOIDDriverUnLoad( _In_ struct _DRIVER_OBJECT *DriverObject){ UNREFERENCED_PARAMETER(DriverObject); UnHook();}typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY64 InLoadOrderLinks; LIST_ENTRY64 InMemoryOrderLinks; LIST_ENTRY64 InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; PVOID SectionPointer; ULONG CheckSum; PVOID LoadedImports; PVOID EntryPointActivationContext; PVOID PatchInformation; LIST_ENTRY64 ForwarderLinks; LIST_ENTRY64 ServiceTagLinks; LIST_ENTRY64 StaticLinks; PVOID ContextInformation; ULONG OriginalBase; LARGE_INTEGER LoadTime;} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath){ UNREFERENCED_PARAMETER(pRegPath); PLDR_DATA_TABLE_ENTRY ldr; ldr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection; ldr->Flags |= 0x20; pDriverObj->DriverUnload = DriverUnLoad; InitHook(); return STATUS_SUCCESS;}
//比較完善的代碼
代碼語言:javascript代碼運行次數:0運行復制
#define PROCESS_TERMINATE (0x0001)#define PROCESS_CREATE_THREAD (0x0002)#define PROCESS_SET_SESSIONID (0x0004)#define PROCESS_VM_OPERATION (0x0008)#define PROCESS_VM_READ (0x0010)#define PROCESS_VM_WRITE (0x0020)#define PROCESS_DUP_HANDLE (0x0040)#define PROCESS_CREATE_PROCESS (0x0080)#define PROCESS_SET_QUOTA (0x0100)#define PROCESS_SET_INFORMATION (0x0200)#define PROCESS_QUERY_INFORMATION (0x0400)#define PROCESS_SUSPEND_RESUME (0x0800)#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)#define PROCESS_SET_LIMITED_INFORMATION (0x2000)注意卸載:ObUnRegisterCallbacks(obHandle);NTSTATUS ProtectProcess(){OB_CALLBACK_REGISTRATION obReg;OB_OPERATION_REGISTRATION opReg;memset(&obReg, 0, sizeof(obReg));obReg.Version = ObGetFilterVersion();obReg.OperationRegistrationCount = 1;obReg.RegistrationContext = NULL;RtlInitUnicodeString(&obReg.Altitude, L"321000");memset(&opReg, 0, sizeof(opReg));opReg.ObjectType = PsProcessType;opReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall;obReg.OperationRegistration = &opReg;return ObRegisterCallbacks(&obReg, &obHandle);}OB_PREOP_CALLBACK_STATUS preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation){HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object);if (pid == PID){if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE){if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_TERMINATE)pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_TERMINATE);if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_VM_OPERATION)pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_VM_OPERATION);if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_VM_READ)pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_VM_READ);if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_VM_WRITE)pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_VM_WRITE);if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_SUSPEND_RESUME)pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_SUSPEND_RESUME);}if (pOperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE){if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_TERMINATE)pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_TERMINATE);if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_VM_OPERATION)pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_VM_OPERATION);if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_VM_READ)pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_VM_READ);if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_VM_WRITE)pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_VM_WRITE);if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_SUSPEND_RESUME)pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_SUSPEND_RESUME);}}return OB_PREOP_SUCCESS;}
三丶BlockBone代碼實現
其實這個代碼在BlockBone中已經實現了。
代碼如下:
首先定義需要的結構
代碼語言:javascript代碼運行次數:0運行復制
#define EX_ADDITIONAL_INFO_SIGNATURE (ULONG_PTR)(-2)typedef union _EXHANDLE{ struct { int TagBits : 2; int Index : 30; } u; void * GenericHandleOverlay; ULONG_PTR Value;} EXHANDLE, *PEXHANDLE;typedef struct _HANDLE_TABLE{ ULONG NextHandleNeedingPool; long ExtraInfoPages; LONG_PTR TableCode; PEPROCESS QuotaProcess; LIST_ENTRY HandleTableList; ULONG UniqueProcessId; ULONG Flags; EX_PUSH_LOCK HandleContentionEvent; EX_PUSH_LOCK HandleTableLock; // More fields here...} HANDLE_TABLE, *PHANDLE_TABLE;typedef struct _HANDLE_TABLE_ENTRY // Size=16{ union { ULONG_PTR VolatileLowValue; // Size=8 Offset=0 ULONG_PTR LowValue; // Size=8 Offset=0 struct _HANDLE_TABLE_ENTRY_INFO * InfoTable; // Size=8 Offset=0 struct { ULONG_PTR Unlocked : 1; // Size=8 Offset=0 BitOffset=0 BitCount=1 ULONG_PTR RefCnt : 16; // Size=8 Offset=0 BitOffset=1 BitCount=16 ULONG_PTR Attributes : 3; // Size=8 Offset=0 BitOffset=17 BitCount=3 ULONG_PTR ObjectPointerBits : 44; // Size=8 Offset=0 BitOffset=20 BitCount=44 }; }; union { ULONG_PTR HighValue; // Size=8 Offset=8 struct _HANDLE_TABLE_ENTRY * NextFreeHandleEntry; // Size=8 Offset=8 union _EXHANDLE LeafHandleValue; // Size=8 Offset=8 struct { ULONG GrantedAccessBits : 25; // Size=4 Offset=8 BitOffset=0 BitCount=25 ULONG NoRightsUpgrade : 1; // Size=4 Offset=8 BitOffset=25 BitCount=1 ULONG Spare : 6; // Size=4 Offset=8 BitOffset=26 BitCount=6 }; }; ULONG TypeInfo; // Size=4 Offset=12} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;/// <summary>/// Input for IOCTL_BLACKBONE_GRANT_ACCESS/// </summary>typedef struct _HANDLE_GRANT_ACCESS{ ULONGLONG handle; // Handle to modify ULONG pid; // Process ID ULONG access; // Access flags to grant} HANDLE_GRANT_ACCESS, *PHANDLE_GRANT_ACCESS;#define IOCTL_BLACKBONE_GRANT_ACCESS (ULONG)CTL_CODE(FILE_DEVICE_BLACKBONE, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)#define STATUS_WAIT_0 ((NTSTATUS)0x00000000L) // winnttypedef BOOLEAN(*EX_ENUMERATE_HANDLE_ROUTINE)(#if !defined(_WIN7_) IN PHANDLE_TABLE HandleTable,#endif IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID EnumParameter );extern "C" NTKERNELAPIBOOLEANExEnumHandleTable( IN PHANDLE_TABLE HandleTable, IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure, IN PVOID EnumParameter, OUT PHANDLE Handle);extern "C" NTKERNELAPIVOIDFASTCALLExfUnblockPushLock( IN OUT PEX_PUSH_LOCK PushLock, IN OUT PVOID WaitBlock);#define ExpIsValidObjectEntry(Entry) ( (Entry != NULL) && (Entry->LowValue != 0) && (Entry->HighValue != EX_ADDITIONAL_INFO_SIGNATURE) )
核心代碼如下:
代碼語言:javascript代碼運行次數:0運行復制
/// <summary>/// Check if process is terminating/// </summary>/// <param name="imageBase">Process</param>/// <returns>If TRUE - terminating</returns>BOOLEAN BBCheckProcessTermination(PEPROCESS pProcess){ LARGE_INTEGER zeroTime = { 0 }; return KeWaitForSingleObject(pProcess, Executive, KernelMode, FALSE, &zeroTime) == STATUS_WAIT_0;}/// <summary>/// Handle enumeration callback/// </summary>/// <param name="HandleTable">Process handle table</param>/// <param name="HandleTableEntry">Handle entry</param>/// <param name="Handle">Handle value</param>/// <param name="EnumParameter">User context</param>/// <returns>TRUE when desired handle is found</returns>BOOLEAN BBHandleCallback(#if !defined(_WIN7_) IN PHANDLE_TABLE HandleTable,#endif IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID EnumParameter){ BOOLEAN result = FALSE; ASSERT(EnumParameter); if (EnumParameter != NULL) { PHANDLE_GRANT_ACCESS pAccess = (PHANDLE_GRANT_ACCESS)EnumParameter; if (Handle == (HANDLE)pAccess->handle) { if (ExpIsValidObjectEntry(HandleTableEntry)) { // Update access HandleTableEntry->GrantedAccessBits = pAccess->access; result = TRUE; } else { } } }#if !defined(_WIN7_) // Release implicit locks _InterlockedExchangeAdd8((char*)&HandleTableEntry->VolatileLowValue, 1); // Set Unlocked flag to 1 if (HandleTable != NULL && HandleTable->HandleContentionEvent) ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);#endif return result;}/// <summary>/// Change handle granted access/// </summary>/// <param name="pAccess">Request params</param>/// <returns>Status code</returns>NTSTATUS BBGrantAccess(IN PHANDLE_GRANT_ACCESS pAccess){ NTSTATUS status = STATUS_SUCCESS; PEPROCESS pProcess = NULL; status = PsLookupProcessByProcessId((HANDLE)pAccess->pid, &pProcess); if (NT_SUCCESS(status) && BBCheckProcessTermination(pProcess)) status = STATUS_PROCESS_IS_TERMINATING; if (NT_SUCCESS(status)) { PHANDLE_TABLE pTable = *(PHANDLE_TABLE*)((PUCHAR)pProcess + 0x418);/*自己根據系統尋找每個EPROCESS的OBJECTTABLE偏移*/ BOOLEAN found = ExEnumHandleTable(pTable, &BBHandleCallback, pAccess, NULL); if (found == FALSE) status = STATUS_NOT_FOUND; } else { } if (pProcess) ObDereferenceObject(pProcess); return status;}
使用方式同上。可以指定進程,然后指定這個進程的一個句柄,將這個句柄提權。
四丶效果圖

可以看到 首先打印的HANDLE 然后進行首次關閉notepad. 因為保護驅動加載了,所以首次結束notepad是失敗的。
然后嘗試進行第二次結束notepad,此時會提示用戶按任意鍵繼續,在等待用戶按任意鍵的時候先把提權驅動加載上,此時返回用戶程序按任意鍵繼續。
繼續之后就會結束被保護的進程。
五 丶 突破游戲保護
本文以常規方式進行演示的,知道原理了那么自己突破應該明白了吧。(注入沒有Open的權限Write的權限Virtual的權限,那么可以提權再用有權的句柄進行操作。。)