栈溢出笔记1.12 栈Cookie
棧Cookie,也叫安全Cookie。我們先來看一看棧Cookie的實現機制,使用的程序為1.2節中的example_2,重點在函數get_print()部分。還記得在1.2節中我們為了演示棧溢出,去掉了編譯設置中的“緩沖區安全檢查(GS)”選項,我們先看看未啟用該選項時的get_print()函數代碼:?
?
圖78 未啟用GS的get_print()函數代碼
然后,啟用該選項,看啟用該選項之后的get_print()函數代碼:?
?
圖79 啟用GS的get_print()函數代碼
函數開頭部分和結尾部分多了上面標注的幾行代碼,結尾還多了一個函數調用。先看看開頭多出來的三行代碼:
/*****************************************************************************/ MOV EAX,DWORD PTR DS:[416000] XOR EAX,EBP MOV DWORD PTR SS:[EBP-4],EAX /*****************************************************************************/- 1
- 2
- 3
- 4
- 5
這三行代碼的操作是從取數據段0x416000處的值,然后與當前的EBP進行異或操作,并將結果保存到棧中EBP-4的位置,回想1.1中的圖,EBP-4的位置應該就是保存的EBP上面的那個(即緊鄰EBP)。也就是說,這段代碼往保存的EBP和局部變量區中間插入了一個值,現在棧變成了這個樣子:?
?
圖80 加Cookie之后的棧
接下來看結尾多出來的三行代碼:
/*****************************************************************************/ MOV ECX,DWORD PTR SS:[EBP-4] XOR ECX,EBP CALL example_.00411014 /*****************************************************************************/- 1
- 2
- 3
- 4
- 5
操作是將保存的Cookie值取處到ECX,然后再與當前EBP異或,然后調用example_.00411014函數。這是做什么呢?EBP是沒有變化的,因此,若保存的Cookie值也沒有變化,則與EBP異或將為原值(即從DS:[416000]取出來的值)。所以,example_.00411014應該是一個檢查Cookie是否發生變化的函數,通過ECX的值來判斷Cookie值是否被修改,從而做一些操作。
究竟是做什么操作,我們不再往下跟,但從1.2節中程序的表現來看,應該是引發了一個異常。?
這就是Cookie的工作原理了,在棧上的局部變量區和保存的返回地址(EIP)之間保存一個值,如果發生了棧溢出,則該值會被修改,從而驗證不通過,引發棧溢出異常。這個Cookie是通過保存于數據段中的一個值與EBP異或得到的。
下面,我們在開啟了GS時的棧中看一看該Cookie值(輸入10個A,不超過緩沖區大小):?
?
圖81 Cookie值
這就是位于EBP和局部變量之間的Cookie值。
我們重啟程序再來看一看:?
?
圖82 Cookie值
它的值變了!這說明DS:[416000]處的值是一個隨機值,每次運行程序都不同。這樣,使得Cookie值難以預測。但好消息是,它的位置是固定的。因此,Cookie的作用相當明確,就是保護下面的返回地址不被修改。
啟用了棧Cookie之后,會進行Cookie值的檢查,因此,繞過的方法之一,就是繞過檢查的步驟。這種方法實際上我們前面已經用到了,由于棧Cookie檢查在函數最后,因此提前引起一次異常,利用SEH就可以繞過Cookie的檢查。當然,依據具體的程序,還有很多其它的方式,具體請看這篇專門講棧Cookie的文章:Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server, David Litchfield。
總結
以上是生活随笔為你收集整理的栈溢出笔记1.12 栈Cookie的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转: eclipse 快捷键列表(功能清
- 下一篇: 数据库自增主键可能产生的问题