天天看點

堆噴射

堆噴射主要用于繞過ASLR。下面示範堆噴射分析與效果。

1.代碼

void heap_spray()

{

  char chunk[LEN] = { 0 };

  memset(chunk, 0x90, LEN - 10);

  strcat(chunk, "shellcode");

  for (int i = 0;i < 100;i++)

  {

    void *p = malloc(LEN);

    strcpy((char *)p, chunk);

    printf("spray %d\n", i);

  }

}

2.windbg分析

  •  !heap -stat:堆統計資訊

_HEAP 002a0000

  Segments 00000001

  Reserved bytes 00100000

  Committed bytes 0009c000

  VirtAllocBlocks 00000000

  VirtAlloc bytes 00000000

_HEAP 00020000...

  •  !heap -stat -h 002a0000//檢視segement 2a0000堆塊大小統計情況

    group-by: TOTSIZE max-display: 20

    size #blocks total ( %) (percent of total busy bytes)

    1000 65 - 65000 (94.88)//大小為0x1000,共0x65個,占比94.88%,可見堆噴射效果較好

    20 6e - dc0 (0.81)

    c00 1 - c00 (0.70)

    bec 1 - bec (0.70...

  •   !heap -flt s 1000:列出所有大小為0x1000的堆塊

    _HEAP @ 2a0000

    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state

    002c9e50 0201 0000 [00] 002c9e58 01000 - (busy)

    002cae58 0201 0201 [00] 002cae60 01000 - (free)

    002cbe60 0201 0201 [00] 002cbe68 01000 - (busy)

    002cce68 0201 0201 [00] 002cce70 01000 - (busy)

    002cde70 0201 0201 [00] 002cde78 01000 - (busy)

    002cee78 0201 0201 [00] 002cee80 01000 - (busy)

  • 0:000> dc 0032df90+0x1000-10//驗證到順序配置設定,并且相臨。同時包含0x8的堆頭。一個堆塊大小為0x1000+0x8.

    0032ef80 90909090 68739090 636c6c65 0065646f ......shellcode.

    0032ef90 1a394b70 88000000 90909090 90909090 pK9.............

    0032efa0 90909090 90909090 90909090 90909090 ................

  •  !address:使用address檢視記憶體屬性

    BaseAddr EndAddr+1 RgnSize Type State Protect Usage

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

    + 0 10000 10000 MEM_FREE PAGE_NOACCESS Free

    + 10000 20000 10000 MEM_MAPPED MEM_COMMIT PAGE_READWRITE Heap [ID: 1; Handle: 00010000; Type: Segment]

    + 20000 30000 10000 MEM_MAPPED MEM_COMMIT PAGE_READWRITE Heap

   Type:

MEM_IMAGE 映射的檔案屬于可執行映像一部分的記憶體。
MEM_MAPPED 映射的檔案不屬于可執行映像一部分的記憶體。這種記憶體包含哪些從頁面檔案映射的記憶體。
MEM_PRIVATE 私有的(即不和其他程序共享)并且未用來映射任何檔案的記憶體。

  

 

   State

MEM_COMMIT 目前已送出給目标使用的所有記憶體。已經在實體記憶體或者頁面檔案中為這些記憶體配置設定了實體的存儲空間。
MEM_RESERVE 所有為目标以後的使用保留的記憶體。這種記憶體還沒有配置設定實體上的存儲空間。
MEM_FREE 目标虛拟位址空間中所有可用記憶體。包括所有未送出并且未保留的記憶體。該Filter 值和RegionUsageFree一樣。

   

           Protect:

Filter value Memory regions displayed
PAGE_NOACCESS Memory that cannot be accessed.
PAGE_READONLY Memory that is readable, but not writable and not executable.
PAGE_READWRITE Memory that is readable and writable, but not executable.
PAGE_WRITECOPY Memory that has copy-on-write behavior.
PAGE_EXECUTE Memory that is executable, but not readable and not writeable.
PAGE_EXECUTE_READ Memory that is executable and readable, but not writable.
PAGE_EXECUTE_READWRITE Memory that is executable, readable, and writable.
PAGE_EXECUTE_WRITECOPY Memory that is executable and has copy-on-write behavior.
PAGE_GUARD Memroy that acts as a guard page.
PAGE_NOCACHE Memory that is not cached.
PAGE_WRITECOMBINE Memory that has write-combine access enabled.
  • !address 0032df90

    Usage: Heap

    Base Address: 002a0000

    End Address: 0033c000

    Region Size: 0009c000 ( 624.000 kB)

    State: 00001000 MEM_COMMIT//已經在實體記憶體中配置設定

    Protect: 00000004 PAGE_READWRITE//可讀寫,但不可執行

    Type: 00020000 MEM_PRIVATE

    Allocation Base: 002a0000

    Allocation Protect: 00000004 PAGE_READWRITE

  • 修改寄存器指令 

    r @eax=1  //将eax置為1

    修改記憶體指令

    ed 80505648 00001234

堆噴射