iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Security

現在是pwn的天下!系列 第 23

【Day-23】Double free

  • 分享至 

  • xImage
  •  

Double Free

1. 什麼是 Double Free?

在程式中,free() 被設計來釋放動態配置的記憶體空間。
Double Free 漏洞就是指 同一個記憶體區塊被 free() 了兩次或以上

這會破壞 malloc/free 的內部資料結構(例如 fastbin freelist、tcache freelist),進而讓攻擊者能夠控制之後 malloc() 返回的記憶體位置。


2. 為什麼會發生 Double Free?

常見原因:

  • 程式邏輯錯誤:同一個指標在多個地方被釋放。
  • Use-After-Free 沒處理好:指標被釋放後,沒有設成 NULL,導致之後還能被 free()

範例程式

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *a = malloc(0x40);
    free(a);
    free(a); // 🚨 Double Free
    return 0;
}

3. glibc 與 Double Free 的演變

glibc 版本 狀態 說明
< 2.26 高度可利用 fastbin 沒有太多檢查,Double Free 幾乎可直接利用
>= 2.26 增加檢查 引入 tcache,針對連續釋放同一 chunk 有檢查,但仍可透過技巧繞過,例如交錯釋放或偽造 fd

4. Double Free 的利用方式

4.1 Fastbin Double Free

假設有一個 chunk A 被 free 了兩次,它會被插入 fastbin freelist 兩次:

fastbin -> A -> A -> ...

之後 malloc() 會依序取出,導致同一個指標被多次分配。
攻擊者可以:

  • 把同一塊記憶體分配給兩個不同的指標
  • 利用寫操作修改另一個變數的內容

4.2 Tcache Double Free

在 glibc 2.26 之後,引入 tcache:

  • Double Free 可以讓 tcache freelist 中存放兩次相同的 chunk
  • 攻擊者可以偽造 freelist 的 fd 指標,控制下一次 malloc() 返回的地址
  • 通常用於 任意地址寫 (Arbitrary Write)

5. 範例展示

5.1 受害程式 (漏洞程式)

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *a = malloc(0x40);
    char *b = malloc(0x40);

    free(a);
    free(b);
    free(a); // 🚨 Double Free

    return 0;
}

5.2 Exploit 思路表格

步驟 操作 freelist 狀態 攻擊者效果
1 free(a) a chunk a 進入 freelist
2 free(b) b -> a chunk b 進入 freelist
3 free(a) again a -> b -> a chunk a 再次進入 freelist
4 malloc() -> a b -> a 指標 a 分配到 chunk a,可控制內容
5 malloc() -> b a 指標 b 分配到 chunk b,可操作 a 內容##

6. 防禦方法

方法 說明
設指標為 NULL 每次 free 後將指標設為 NULL,避免重複釋放
使用安全記憶體管理 如 smart pointer 或 RAII 機制
glibc 檢查 新版 glibc 會檢查 double free,但仍需注意程式邏輯漏洞

7. 總結

  • Double Free 是 Heap Exploitation 的經典入門手法
  • 核心在於破壞 allocator 的 freelist 結構
  • 即使在現代 glibc 中,Double Free 仍可透過 tcache 進行利用
  • 建議每次 free 後設置指標為 NULL,並小心程式邏輯

上一篇
【Day-22】one-gadget用法及介紹 (內附Lab)
下一篇
【Day-24】Linux Kernel 是什麼?作業系統的核心介紹
系列文
現在是pwn的天下!30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言