技術原創 緩衝區溢出
相信大家對緩衝區溢出並不陌生,此片文章將帶領大家從最基礎的緩衝區開始了解緩衝區溢出攻擊。
主要原理就是通過往程序的緩衝區寫超出其長度的內容,造成緩衝區的溢出,從而破壞程序的堆棧,使程序轉而執行其它指令,以達到攻擊的目的。造成緩衝區溢出的原因是程序中沒有仔細檢查用戶輸入的參數。
拿個簡單的C/C++程序引入:
int main()
{
char name[10];
scanf("%s", name);
printf("輸入的是:%s
", name);
system("pause");
return 0;
}
環境:win10+VS2013+VC6.0+OD
實驗前關一下安全檢測。
先不說問題存在哪,編譯完我們直接運行。
我們連續輸入了9個字元後程序是正常執行流程的,最後列印出來了。
可當我們連續輸入11個字元後。
崩潰了。。。
我們知道SCANF()當沒有對NAME進行長度檢驗的時候就會造成數組溢出。
對程序下個斷點後跑起來看看問題。
在調試前,建議大家把異常處理的忽略都關掉。
關掉後所有的錯誤都可以看到了,方便我們知道哪裡的異常提示。
當CALL之後呢008F1BC8會被壓入堆棧,再CALL之後008F1BCD也會被壓入進去。
原因是當CALL執行完調用的函數後,EIP指針能夠返回到CALL指令的下一跳執行的指令地址了。但是原來的返回ret eip地址被改了。
跟進main函數入口。
Push ebp
Mov ebp,esp
Sub esp,0D4H
經典的main入口彙編代碼。
雖然調試器不一樣彙編代碼也有區別,但結果是一樣的。
執行完後的樣子
套個此生大牛的圖就是這樣的,最原理的圖。
此圖讓剛入門的朋友更好理解。
不好意思,拿錯了
上圖流程就是我們從scanf()讀取輸入的數據寫入到name的地址中,但是分配的只有10,超過10後的字元將被寫入到函數執行完後的EIP地址(ret eip)
也就是說把正常程序執行的流程給覆蓋掉了,來張比較形象一些的圖。
攻擊代碼這裡所說的就是shell code的,通過上圖我們可以知道RET EIP的地址了,也就是name+14的地址。
為了可觀一些我把該代碼轉用VC6.0編譯。
程序提示了616161就是a
我們的輸入的A把RET EIP地址給覆蓋掉了,操作系統不明白aaaa是啥玩意兒,所以程序提示了不能讀。當程序發生異常後會優先發給調試器,調試器就中斷了。
斷在了異常處理函數
這裡不用管他,我們使用windbg來找ret eip 的地址。
0012FF7D就是我們要的地址了,這裡我的操作系統並沒有kernel棧隨機化。
總結:在整個溢出過程中申明了空間,但是所操作的數據超過了buff空間,也就是操作越界,覆蓋了棧中的ret eip單元數據,把main函數的返回地址改了,這樣以來main操作結束後返回的就是這個地址作為返回地址運行。
可在實際情況中是沒有源碼的,我們還需要對buff寫入多長後會發生溢出等進行逆向分析動態調試,還需要考慮程序流及shellcode空間的存放(shellcode本質上就是一段機器碼)等以及ASLR,以上所涉及知識也是最簡單同時最為核心的。
參考資料:
※勒索軟體「假面」系列——免流軟體(二)
※史上最瘮人木馬「詭娃」來襲!360安全衛士強勢攔截
TAG:威客安全 |