安全程式設計 Lab 5:用 GDB 理解 Buffer Overflow(附影片與指令整理)
這是「安全程式設計」課程的 Lab 5 輔助教材,主題是用 GDB 觀察程式執行時的堆疊,並實際理解 Buffer Overflow(緩衝區溢位)的成因。下方影片是完整的操作示範,文字部分整理了練習時最常用到的觀念與指令。
影片教學
什麼是 Buffer Overflow?
當程式把超過緩衝區大小的資料寫進記憶體,例如用 gets()、strcpy() 這類不檢查長度的函式,多出來的資料就會覆蓋到相鄰的記憶體。在堆疊上,這可能蓋掉函式的返回位址(return address),讓攻擊者控制程式下一步要執行的位置。
練習時常用的 GDB 指令
| 指令 | 用途 |
|---|---|
break main | 在 main 函式設中斷點 |
run | 執行程式 |
disas main | 反組譯 main,找出要觀察的位置 |
info registers | 查看暫存器,例如 rip / rsp / rbp |
x/40wx $rsp | 以 16 進位檢視堆疊內容 |
next / step | 單步執行(不進入/進入函式) |
continue | 繼續執行到下一個中斷點 |
實驗環境的編譯參數
現代編譯器與作業系統預設開啟多種保護,練習時通常會先關閉,觀察完原理再逐一打開比較:
gcc -g -fno-stack-protector -z execstack -no-pie vuln.c -o vuln
-fno-stack-protector:關閉 Stack Canary-z execstack:讓堆疊可執行(關閉 NX)-no-pie:關閉 PIE,讓程式位址固定- 另外可用
checksec檢查執行檔開啟了哪些保護
如何防禦 Buffer Overflow?
- 改用有長度限制的函式,例如
fgets()、strncpy()、snprintf() - 保持 Stack Canary、NX、ASLR、PIE 等保護開啟
- 開發時用 AddressSanitizer(
-fsanitize=address)提早抓出記憶體錯誤
