緩衝區溢位攻擊實驗實驗報告
緩衝區溢位攻擊實驗
原理:
緩衝區溢位是指程式試圖向緩衝區寫入超出預分配固定長度資料的情況。這一漏洞可以被惡意使用者利用來改變程式的流控制,甚至執行程式碼的任意片段。這一漏洞的出現是由於資料緩衝器和返回地址的暫時關閉,溢位會引起返回地址被重寫。
注:
資料緩衝器:當資料在具有不同傳輸能力的元件之間通過時,用來暫存這些資料的儲存器;
實驗準備:
系統使用者名稱 shiyanlou
實驗樓提供的是 64 位 Ubuntu linux,而本次實驗為了方便觀察彙編語句,我們需要在 32 位環境下作操作,因此實驗之前需要做一些準備。
輸入命令安裝一些用於編譯 32 位 C 程式的軟體包:
初始設定
1、Ubuntu 和其他一些 Linux 系統中,使用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,這使得猜測準確的記憶體地址變得十分困難,而猜測記憶體地址是緩衝區溢位攻擊的關鍵。因此本次實驗中,我們使用以下命令關閉這一功能
2、此外,為了進一步防範緩衝區溢位攻擊及其它利用 shell 程式的攻擊,許多shell程式在被呼叫時自動放棄它們的特權。因此,即使你能欺騙一個 Set-UID 程式呼叫一個 shell,也不能在這個 shell 中保持 root 許可權,這個防護措施在 /bin/bash 中實現。
linux 系統中,/bin/sh 實際是指向 /bin/bash 或 /bin/dash 的一個符號連結。為了重現這一防護措施被實現之前的情形,我們使用另一個 shell 程式(zsh)代替 /bin/bash。下面的指令描述瞭如何設定 zsh 程式:
所以,就是將原連結sh刪除,之後重建一個連結sh指向shell從而撤銷防禦
3、
- 輸入命令 linux32 進入32位linux環境。
編寫漏洞程式碼
功能:讀取一個名為“badfile”的檔案,並將檔案內容裝入“buffer”。
編寫攻擊程式碼
- 我們的目的是攻擊剛才的漏洞程式,並通過攻擊獲得 root 許可權。
這個程式碼是用來進行攻擊的,但是在後來攻擊失敗,出現了segmentation fault
後來發現是因為複製時出現了縮排混亂導致組合語言那裡多了一個‘/’
- 現在我們要得到 shellcode 在記憶體中的地址,輸入命令進入 gdb 除錯:
由此得到了shell的地址,並且將之填入了"??"處
- 注:“disass”是"disassemble"反彙編命令的縮寫
反彙編
現在修改 exploit.c 檔案,將 \x??\x??\x??\x?? 修改為計算的結果 \x14\xd0\xff\xff,注意順序是反的。
- 然後,編譯 exploit.c 程式
執行
- 成功獲得root許可權
原理及其防範:
- 原理:通過往程式的緩衝區,寫入超出其長度的內容,造成緩衝區的溢位,從而破壞程式的“堆疊”,使程式轉而執行其它指令,以達到攻擊的目的。
- 隨便往緩衝區中填東西造成它溢位,一般只會出現“分段錯誤”,而不能達到攻擊的目的。最常見的手段是,通過製造緩衝區溢位,使程式執行一個使用者shell(計算機殼層,屬於“命令解析器”,用於接收使用者的命令),再通過shell執行其它命令。如果該程式屬於root且有suid許可權的話,攻擊者就獲得了一個有“root許可權”(系統許可權的一種,也叫“根許可權”)的shell,這樣就可以對系統進行任意操作了。
- 防範方法:
1.系統管理上:
1)關閉不需要的特權程式。
2)及時給程式漏洞打補丁。
2.軟體開發過程中的防範策略
1)強制寫正確的程式碼的方法。
只要在所有拷貝資料的地方進行資料長度和有效性的檢查,確保目標緩衝旦中資料不越界並有效,則就可以避免緩衝區溢位,更不可能使程式跳轉到惡意程式碼上。
2)通過作業系統使得緩衝區不可執行,從而阻止攻擊者殖入攻擊程式碼。
通過使被攻擊程式的資料段地址空間不可執行,從而使得攻擊者不可能執行被植入被攻擊程式輸入緩衝區的程式碼,這種技術被稱為緩衝區不可執行技術。
3)利用編譯器的邊界檢查,來實現緩衝區的保護
這個方法使得緩衝區溢位不可能出現,從而完全消除了緩衝區溢位的威脅,但是相對而言,代價比較大。
4)在程式指標失效前進行完整性檢查
雖然這種方法不能使得所有的緩衝區溢位失效,但它能阻止絕大多數的緩衝區溢位攻擊;而能夠逃脫這種方法保護的緩衝區溢位,也很難實現。
5)改進C語言函式庫
C語言中存在緩衝區溢位攻擊隱患的系統匾數有很多。例如gets(),sprintf(),strcpy(),strcat(),fscanf(),scanf(),vsprintf()等。可以開發出更安全的封裝了若干己知易受堆疊溢位攻擊的岸函式。
6)使堆疊向高地址方向增長
使用的機器堆疊壓入資料時向高地址方向前進,那麼無論緩衝區如何溢位,都不可能覆蓋低地址處的函式返回地址指標,也就避免了緩衝區溢位攻擊。但是這種方法仍然無法防範利用堆和靜態資料段的緩衝區進行溢位的攻擊。