zoukankan      html  css  js  c++  java
  • BitMap大小探索之CreateCompatibleBitmap

    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
    ", hExploitBit);
    
    
    	PTEB Teb = NtCurrentTeb();
    	PPEB Peb = Teb->ProcessEnvironmentBlock;
    	if (Peb == NULL)
    	{
    		return FALSE;
    	}
    
    	printf("[+]Peb Pointer address : %p
    ", Peb);
    	PBYTE  GdiSharedHandleTable = *(PBYTE *)((ULONGLONG)Peb + 0xF8);
    	if (GdiSharedHandleTable == NULL)
    	{
    		return FALSE;
    	}
    	printf("[+]GdiSharedHandleTable Pointer address: %p
    ", GdiSharedHandleTable);
    
    
    	//获取 漏洞对象 内核地址
    	pExpBitmapObj = *(PBYTE *)((ULONGLONG)GdiSharedHandleTable + sizeof(HANDLEENTRY) * (((ULONGLONG)hExploitBit) & 0xffff));
    
    	printf("[+]dwExpBitmapObj Lookup address: %p
    ", pExpBitmapObj);
    
    };
    
  • 相关阅读:
    渲染管线中的顶点变换
    导入图片时设置默认格式
    查找丢失组件的预制体
    移动到目标点的方法
    关于material和sharedMaterial的问题
    代码创建动画状态机
    设计模式学习笔记--访问者模式
    .net core 基于Dapper 的分库分表开源框架(core-data)
    .Net 微服务架构技术栈的那些事
    Asp.Net Core 中IdentityServer4 实战之角色授权详解
  • 原文地址:https://www.cnblogs.com/hongyeHK/p/13451734.html
Copyright © 2011-2022 走看看