想必大家玩 CTF 時都有碰過那種程式會要求你輸入一些東西,結果把很長很長的輸入丟進去就崩了。這種題目就是 — buffer overflow!
什麼是 Buffer Overflow(緩衝區溢位)?
- 當一個程式把超過預期長度的資料寫入固定大小的緩衝區(buffer)時,超出的部分會覆寫相鄰記憶體(stack 上的 return address、saved rbp、或鄰近變數)。
- 最經典的是 stack-based buffer overflow:利用這點覆寫 return address,使函式返回時跳到攻擊者控制的位置
- 另一類是 heap overflow:覆寫 heap metadata 或 function pointer,常用於更複雜的利用場景
常見會造成 overflow 的因素
危險/不安全的輸入函式(C)
- ex:
gets()
, scanf("%s", buf)
, strcpy()
, strcat()
, sprintf()
(無邊界檢查版本)
- 這些函式不會檢查目標 buffer 大小,當輸入長於 buffer,就會覆寫鄰近記憶體(stack/heap)。
錯誤使用的長度/邊界檢查
- ex:
memcpy(buf, src, len)
但 len
是攻擊者可控或沒有驗證 buf
長度。
- 即使使用「看起來安全」的函式,若長度參數由外部或計算錯誤,仍會溢位。
Heap metadata / 記憶體管理錯誤
- ex:對 heap buffer 做 overflow,覆寫 malloc/free metadata(fd/ bk 或 tcache)或 function pointer。
- 會導致任意寫/任意執行,複雜但威力大。
缺乏輸入驗證(任意長度/型態)
- ex:web / daemon 接收未限制長度的字段(如 header、username),直接拋給 C 層函式處理。
- 攻擊面來自高層到低層聯動,如果任一層沒檢查,底層會被覆寫。
基本流程
-
找 vuln(找到能 overflow 的函式)
- 常見函式:
gets
, strcpy
, strncpy
, scanf("%s")
, read
等危險函數
- 透過反編譯 / 觀察源碼或用 gdb 追蹤,找出那個 buffer 的大小與 return address 在 stack 的偏移。
-
找 offset(多少字元會覆寫 return)
- 使用 pattern(pwntools / metasploit 的 cyclic)產生唯一序列,送進程式,當程式崩潰時查看 crashed RIP 或 EIP,反推 offset。
- 範例:
payload = cyclic(200)
, 在崩潰後 cyclic_find(0x6161616c)
得到 offset。
-
判斷保護機制
- NX(non-executable stack):若啟用,不能放 shellcode 在 stack 執行,改用 ROP。
- ASLR(地址隨機):若啟用,需要先 leak libc 或 binary base 才能精準覆寫 return。
- Canary(stack cookie):若存在,要先 leak canary 或利用資訊洩露來繞過。
- PIE:如果 binary 為 PIE,binary 基址也會隨機化,需 leak base。
這題我們先打開source code看一下,可以發現他write_buffer
是用scanf
來讀取我們的輸入,所以可能可以overflow!

觀察check_win
可以發現這題的目標是將safe_var
改成pico

進行nc連線後,我們可以發現我們的input_data
跟safe_var
距離相差為 0x651b62b202d0 - 0x651b62b202b0 = 32

我們可以寫入32個A然後接pico,將safe_var
的內容填為pico,然後就可以獲得這題的flag啦!

題單
-
heap 0
-
heap 2
-
heap 3
-
clutter-overflow
-
buffer overflow 0
-
buffer overflow 1
-
buffer overflow 2
以上就是今天的內容啦
想看更多,記得明天再來喔~