1. 程式人生 > >認識堆溢位

認識堆溢位

學習資料:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/heap/heapoverflow_basic/

之前學了一些棧溢位的知識和方法,首先比較了一下堆溢位和它的區別

堆上並不存在返回地址等可以讓攻擊者直接控制執行流程的資料,因此我們一般無法直接通過堆溢位來控制 EIP

那怎麼辦呢,第一步要了解一些堆的知識,一邊學的時候一邊查詢就好了,知識點我只看了簡單的部分

對的分配:通常來說堆是通過呼叫 glibc 函式 malloc 進行分配的,在某些情況下會使用 calloc 分配。calloc 與 malloc 的區別是 calloc在分配後會自動進行清空,同時還有realloc,大概就是再分配時會根據你需要的size大小進行調整堆大小,具體怎麼調整可以百度一下

堆溢位和棧溢位的危險函式都差不多

  • 輸入
    • gets,直接讀取一行,忽略 '\x00'
    • scanf
    • vscanf
  • 輸出
    • sprintf
  • 字串
    • strcpy,字串複製,遇到 '\x00' 停止
    • strcat,字串拼接,遇到 '\x00' 停止
    • bcopy

堆溢位肯定需要覆蓋區域的大小:和棧溢位不同的是(我們請求多少棧空間就給多少),申請對空間的時候不知道為什麼對我們特別好,偏要多給我們一點,為什麼會多一些呢?,有兩個原因:對齊;堆頭部

對齊就不多做介紹了,搜一下就好了,無非就是32位與64位的不同

說到堆頭部,就可以介紹一下堆的結構是什麼樣的了

struct malloc_chunk {

  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */
  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */

  struct malloc_chunk* fd;         /* double links -- used only if free. */
  struct malloc_chunk* bk;

  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
};

prev_size:

前一塊chunk的大小(若前一塊chunk空閒,否則存放前一塊chunk的資料,這也就是chunk的複用)

size:

該 chunk 的大小

fd,bk:

chunk 處於分配狀態時,從 fd 欄位開始是使用者的資料。chunk 空閒時,會被新增到對應的空閒管理連結串列中,其欄位的含義如下

fd 指向下一個(非物理相鄰)空閒的 chunk

bk 指向上一個(非物理相鄰)空閒的 chunk

通過 fd 和 bk 可以將空閒的 chunk 塊加入到空閒的 chunk 塊連結串列進行統一管理

fd_nextsize, bk_nextsize:

也是隻有 chunk 空閒的時候才使用,不過其用於較大的 chunk(large chunk)。

fd_nextsize 指向前一個與當前 chunk 大小不同的第一個空閒塊,不包含 bin 的頭指標。

bk_nextsize 指向後一個與當前 chunk 大小不同的第一個空閒塊,不包含 bin 的頭指標。

一般空閒的 large chunk 在 fd 的遍歷順序中,按照由大到小的順序排列

 

那我們就可以推斷出分配的記憶體是多少了,借用CTFWIKI中的例子,假設在64位程式中,我們申請24位元組的堆空間

首先chunk頭部16位元組是不能存放我們需要的資料的,但是還是需要申請

再則因為本快堆已經被分配了,所以下一塊的pre可以寫奔塊堆的資料,可以多用8位元組

所以實際分配的位元組大小:24+16-8=32位元組

 

稍微看了一下堆溢位的小技巧之後,覺得認識堆回收之後的管理也是重要的

以下圖片來自CTFWIKI

除了fastbin,一共128個bin放在一起,這些要麼極其有規律,要麼極其沒規律,搜一下就好了,這裡單獨提一下fastbin,如下圖

還有一些像top chunk和last remainder還算好理解,就暫時不介紹了

這些就是chunk大概得了,其實頂上依次還有heap和arena,暫時可能hold不住就先不瞭解了