在本篇文章中,我們將介紹另一種常見的 Heap 漏洞 — Double Free。這個漏洞發生在程式碼嘗試釋放相同的記憶體區塊兩次的情況下,會導致記憶體管理器內部資料結構被破壞。
Double Free 是指程式錯誤地釋放了一塊已經被釋放過的記憶體區塊,這樣的操作會影響記憶體管理中的資料結構,導致其錯誤地認為該區塊可以被重複分配。由於某些記憶體管理實作允許重複分配的區塊,因此攻擊者可以通過 Double Free 操作來覆蓋其他記憶體內容,進行進一步的攻擊。
Heap 分配器通常使用不同的資料結構來管理已分配和未分配的記憶體。釋放記憶體時,該記憶體區塊會被重新放回這些資料結構中,以供後續的分配操作。如果一個區塊被釋放了兩次,該區塊可能會被多次分配給不同的變數,這會導致多個指標指向相同的記憶體位置,從而產生漏洞。
以下範例程式展示 Double Free:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *a = malloc(5);
char *b = malloc(5);
char *c = malloc(5);
free(a);
free(b);
free(a);
char *d = malloc(5);
char *e = malloc(5);
char *f = malloc(5);
return 0;
}
整個城市的架構如下:
當 a 被釋放後,fastbin 的狀態為
head -> a -> tail
b 被釋放後狀態為:
head -> b -> a -> tail
當 a 再次被釋放時(Double Free)
head -> a -> b -> a -> tail
當 d 再次分配記憶體時,它會獲取 a 的位址
head -> b -> a -> tail
當 e 分配記憶體時,他會獲得 b 的位址
head -> a -> tail
此時當 f 再次分配記憶體時,它也會獲取 a 的位置,導致 d 和 f 指向同一塊記憶體,導致攻擊者可用來篡改記憶體區塊。