05.08 源碼是這樣審計的

緩衝區溢出算是安全界常見的漏洞,也是一種最初級的漏洞,但是這種漏洞時至今日依舊層出不窮。大部分由於項目龐大,調用邏輯層次複雜,以及測試時測試用例問題,不能及時發現這類漏洞。

一. 緩衝區溢出的原因。

由於緩衝區溢出而使得有用的存儲單元被改寫,往往會引發不可預料的後果。程序在運行過程中,為了臨時存取數據的需要,一般都要分配一些內存空間,通常稱這些空間為緩衝區。如果向緩衝區中寫入超過其本身長度的數據,以致於緩衝區無法容納,就會造成緩衝區以外的存儲單元被改寫,這種現象就稱為緩衝區溢出。緩衝區長度一般與用戶自己定義的緩衝變量的類型有關。

總結以上原因,可以獲得緩衝區溢出的兩個必要條件。

1. 緩衝區。

2. 對緩衝區操作造成緩衝區外的存儲單元的數據被改寫。

找到原因後可以總結代碼中出現的情況。

緩衝區: 數組,malloc/new 申請, struct和class中數組。

寫入操作:對緩衝寫入操作時,沒有對長度做校驗,導致數據被覆蓋改寫。(strcpy,strcat,scanf,memcpy, memmove, memeccpy Getc(),fgetc(),getchar;read,printf等函數)。

二. 常見的代碼審計工具弱點

代碼審計對複雜項目的審計效果不好:

1.函數調用是個複雜的過程,當審計工具找到敏感函數時,回溯函數的調用路徑常常會遇到困難。

2. 如果程序使用了複雜框架,代碼審計工具往往由於缺乏對框架的支持,從而造成誤報或漏報。

三. 源碼中白盒審計分析

本次審計的開源軟件為Dmitry1.3a(源碼自行下載).用到的工具sourceinsight,gdb,peda。

使用sourceinsight對源碼進行解析。

1. 查找所有容易產生溢出的函數調用點。

是否對長度有控制,有控制需要查看控制是否合理,不合理可能會引起溢出。沒有長度控制是很大隱患點。

使用sourceinsgiht可以在工程所有文件中查找容易引起溢出的函數的代碼和文件。

逐個查看函數調用是否安全。

2. 逐個分析是否存在可能溢出

溢出原因對緩衝區操作時沒有對緩衝區空間的大小進行校驗。

如果使函數的參數,需要查找其調用函數,查看實參參入時長度是否和函數體內長度一致。如果小於實參長度,就容易產生溢出。

找到可疑點,並做記錄。

可疑點1.

源碼是這樣審計的

可疑點2:

源碼是這樣審計的

可疑點3:函數內部定義fhost最大值為128

源碼是這樣審計的

但是main函數內部調用時沒有檢查長度。

源碼是這樣審計的

可疑點4:函數內部定義為hostwww最大長度為64.

源碼是這樣審計的

但是調用函數main裡面。

源碼是這樣審計的

可疑點5:

源碼是這樣審計的

但是調用函數main裡面:

源碼是這樣審計的

可疑點6:

源碼是這樣審計的

在main函數里面調用,參數strings被輸入時沒有長度驗證。

源碼是這樣審計的

四. 驗證可疑點

對源代碼做了白盒設計分析後,需要對程序的流程和數據做驗證分析,輸入引發溢出的數據,查看是否能夠引起溢出。

驗證可疑點1:

使用gdb調試程序。

設置其參數:set args -oBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB aaaaaaaaaaaaaaa(-o選項,當optorg != 最後一個參數的時候)執行strcpy(outputfile,optarg); 其中outputfile[64]。參數中104個B。可以引發溢出。

運行查看結果:

源碼是這樣審計的

可以看到outputfile被寫入BBB,超過了64位的長度。 但是沒有引發異常。

查看outputfile的定義,是一個全局變量,被寫入超長數據覆蓋一部分數據,數據並沒有使用,所以沒有引發異常。

源碼是這樣審計的

驗證可疑點2:

Gdb調試,設置設置參數,使參數超過128個字符即可產生溢出。在strcpy(host_name,argv[argc - 1]);處下斷點。

set argsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

斷下後,查看未執行strcpy前host_name的數據。

源碼是這樣審計的

執行後,查看host_name的數據。

源碼是這樣審計的

可以看到數據被覆蓋,超過了128. 查看寄存器,大部分寄存器都被覆蓋為

源碼是這樣審計的

驗證可疑點3:

參數長度計算

源碼是這樣審計的

超過128+128+64的長度才能覆蓋數據,引發溢出。

源碼是這樣審計的

驗證可疑點4:

查看引發溢出的條件

源碼是這樣審計的

只有輸入長度大於64+128+4+4+4+4+4後的長度才能引發異常。但不能超過可疑點3的長度。

超過後會引發可疑點3.

設置參數:

set args AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

源碼是這樣審計的

可疑點5和可疑點4類似,輸入數據容易引發可疑點3和可疑點4的溢出。略過。

驗證可疑點6:

設置運行參數:

set args -o AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

跟蹤到函數中,執行完strcat(sendbuff, string2),可以看到數據被覆蓋。

源碼是這樣審計的

源碼是這樣審計的

五. 總結

本次緩衝區溢出主要講解的是棧溢出。純手工審計是為了鍛鍊自己在代碼審計時對漏洞的敏感度。本次用到的Dmitry1.3a是一款信息挖掘的工具。大家在審計或者滲透時用到工具如果是開源的,可以對源碼進行審計和分析,可以同時提高審計能力和工具實現的原理。


分享到:


相關文章: