《缺陷周話》第5期:越界訪問
前言
程式碼審計是使用靜態分析發現原始碼中安全缺陷的方法,能夠輔助開發或測試人員在軟體上線前較為全面地瞭解其安全問題,防患於未然,因此一直以來都是學術界和產業界研究的熱點,並且已經成為安全開發生命週期SDL和DevSecOps等保障體系的重要技術手段。
360程式碼衛士團隊基於自主研發的國內首款原始碼安全檢測商用工具,以及十餘年漏洞技術研究的積累,推出“缺陷周話”系列欄目。每週針對CWE、OWASP等標準中的一類缺陷,結合例項和工具使用進行詳細介紹,旨在為廣大開發和安全人員提供程式碼審計的基礎性標準化教程。
一、越界訪問
越界訪問簡單的說就是預先申請了一塊記憶體,但在使用這塊記憶體的時候超出了申請的範圍從而引發越界。例如當程式訪問一個數組中的元素時,如果索引值超出陣列的長度,就會訪問陣列之外的記憶體。C/C++ 沒有對陣列做邊界檢查,不檢查下標是否越界可以提升程式執行的效率,但同時也把檢查是否越界的任務交給了開發人員,因此開發人員在編寫程式時,需要額外注意避免越界訪問。
二、 越界訪問的危害
越界訪問是 C/C++ 語言中常見的缺陷,它並不一定會造成編譯錯誤,導致的後果也不確定。當出現越界時,由於無法得知被訪問空間儲存的內容,所以會產生不確定的行為,可能是程式崩潰、運算結果非預期,也有可能沒有影響。2018年1月至9月,CVE中越界訪問9個相關漏洞中,有8個來自於開源專案FFmpeg,部分漏洞資訊如下:
CVE-2018-1999015 | FFmpeg commit 5aba5b89d0b1d73164d3b81764828bb8b20ff32a 之前版本中的 ASF_F 格式分離器存在陣列越界讀取漏洞,導致棧記憶體讀取。 |
---|---|
CVE-2018-1999014 | FFmpeg commit bab0716c7f4793ec42e05a5aa7e80d82a0dd4e75 之前版本中的 MXF 格式分離器存在陣列越界訪問漏洞。攻擊者可利用該漏洞造成拒絕服務。 |
CVE-2018-1999010 | FFmpeg commit cced03dd667a5df6df8fd40d8de0bff477ee02e8 之前版本中的 mms 協議存在多個數組越界訪問漏洞。攻擊者可利用該漏洞造成拒絕服務。 |
三、示例程式碼
本節示例程式碼源於 SamateJuliet Test Suite forC/C++v1.3( ofollow,noindex" target="_blank">https://samate.nist.gov/SARD/testsuite.php ),原始檔名:CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_01.c。
3.1 缺陷程式碼
上述示例程式碼在第48行 對 data 的長度 進行了判斷,但只判斷了長度是否為負數,並沒有對上限進行限制(邊界檢查不完整),當 data 的值大於 9 時,在第50行處 buffer[data] 的陣列 下標越界。
使用360程式碼衛士對上述示例程式碼進行檢測,可以檢出“越界訪問”缺陷,顯示等級為高。如圖1所示:
圖1 越界訪問檢測示例
3.2 修復程式碼
在上述修復程式碼中,在第48行中對 data 的邊界進行了完整的檢查,因此避免傳入第50行 buffer[data]時越界。
使用360程式碼衛士對修復後的程式碼進行檢測,可以看到已不存在“越界訪問”缺陷。如圖2:
圖2 修復後檢測結果
四、如何避免越界訪問
要避免越界訪問,需要注意以下幾點:
(1)進行有效的邊界檢查,確保操作在合法的範圍之內。尤其當使用外部輸入資料作為資料來源進行記憶體相關操作時,應格外注意進行邊界檢查,汙染資料是造成越界訪問的重要原因之一。
(2)顯式的指定陣列邊界,不僅可以使程式的可讀性提高,同時,大多數的編譯器在陣列長度小於初始化值列表的長度時會給出警告,這些警告資訊可以幫助開發人員儘早發現越界問題。
(3)在使用迴圈遍歷陣列元素時,注意防範 off-by-one(一個位元組越界)的錯誤。
*本文作者:360程式碼衛士,轉載請註明來自FreeBuf.COM