緩衝區溢出算是安全界常見的漏洞,也是一種最初級的漏洞,但是這種漏洞時至今日依舊層出不窮。大部分由於項目龐大,調用邏輯層次複雜,以及測試時測試用例問題,不能及時發現這類漏洞。
一. 緩衝區溢出的原因。
由於緩衝區溢出而使得有用的存儲單元被改寫,往往會引發不可預料的後果。程序在運行過程中,為了臨時存取數據的需要,一般都要分配一些內存空間,通常稱這些空間為緩衝區。如果向緩衝區中寫入超過其本身長度的數據,以致於緩衝區無法容納,就會造成緩衝區以外的存儲單元被改寫,這種現象就稱為緩衝區溢出。緩衝區長度一般與用戶自己定義的緩衝變量的類型有關。
總結以上原因,可以獲得緩衝區溢出的兩個必要條件。
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是一款信息挖掘的工具。大家在審計或者滲透時用到工具如果是開源的,可以對源碼進行審計和分析,可以同時提高審計能力和工具實現的原理。
閱讀更多 網絡安全晴雨表 的文章