今天的文章會介紹一種 Heap 攻擊手法 - House of Force,它不同於其他基於 fastbins 或 small bins 的攻擊,House of Force 的目標是直接利用 top chunk。它位於 Heap 的最末端,並且不屬於任何特定的 bin。因此,攻擊者可以操控 top chunk 實現從 malloc 返回任意位址。
在介紹攻擊手法前,先介紹 Top Chunk,在每次 malloc 操作分配記憶體時,Top Chunk 是最後被使用的區塊。當 Heap 沒有其他合適大小的區塊時,malloc 會嘗試從 Top Chunk 中分配記憶體,並將 Top Chunk 往前推進,佔據更多的記憶體空間。因此,Top Chunk 是一個動態擴展的區塊,邊界會隨著分配記憶體的需求而改變。
此攻擊的首要目標是找到 Top Chunk 並準備一個可以影響其大小的緩衝區。
當成功找到到當前的 Top Chunk 地址後需要覆蓋內容到 Top Chunk 的 Header 的 size 欄位。接著就能將其修改為一個非常大的值,例如 -1 或 0xFFFFFFFFFFFFFFFF,這會讓程式認為 top chunk 擁有幾乎無限的記憶體空間。在這種情況下,malloc 在後續的記憶體分配請求中會優先嘗試使用 top chunk 來滿足需求,而不會從其他區塊進行分配。這樣的結果使得我們可以利用 malloc 函數操控分配的位置。
一旦掌控了 top chunk,我們的目標是計算出一個適當的請求大小,使得 malloc 返回我們希望分配的特定記憶體地址。舉例來說,假設我們希望 malloc 返回的指標指向一個變數 victim,這個變數的位置就是我們想要覆蓋的記憶體。
通過計算 victim 和當前 top chunk 之間的距離可以確定 malloc 的大小。這個大小應該是 victim 地址減去當前 top chunk 的起始地址,再扣除掉 top chunk 的 header(包括 size 和 prev_size 的大小)。計算方式如下:
requestSize = (size_t)victim - (size_t)top_chunk - 2 * sizeof(long long) - sizeof(long long);
由於 Heap 分配過程中可能會四捨五入,因此在計算中會額外減去 8 Bytes,以確保大小正確。這樣可以讓 malloc 回傳的指標剛好指向 victim 地址,接著發出一個剛剛計算出的 malloc 請求。這個請求會使用 top chunk,並且進一步推進它,使得下一次分配時,top chunk 的起始位置已經到達我們指定的 victim 地址。
此時,top chunk 的指針被移動到了 victim,代表之後 malloc 的調用都會回傳這個地址。由於 victim 已經成為下一個可分配的 Chunk,因此我們可以在後續分配中覆蓋 victim 所在的記憶體內容。
當我們再次調用 malloc 時,分配的 Chunk 的起始地址將會是 victim。這樣,我們可以修改 victim 變數所在的記憶體內容,從而達成覆蓋的效果。實現任意記憶體覆蓋。