龍剛 何建安 高嵩曾奕 張生林


摘要:通過比較國內外C/C++源代碼安全檢測技術的發展狀況,闡述了研制C/C++源代碼安全檢測系統的必要性。討論了C/C++源代碼安全檢測領域的關鍵技術,描述了C/C++源代碼安全檢測系統的主要功能、系統架構和實現途徑,并指出了C/C++源代碼安全檢測系統下一步的改進方向。
關鍵詞:源代碼 軟件安全性 靜態分析
中圖分類號:TP311 文獻標識碼:A 文章編號:1007-9416(2016)06-0150-02
Abstract:Through the development status of domestic and foreign C/C++ source code security detection technology, this paper expounds the necessity of the development of C/C++ source code security detection system. Discuss the key technology in the field of C/C++ source code security detection, describes the C/C++ source code security detection system, the main function, system architecture and realization method, and points out that the C/C++ source code security detection system further improvement direction.
Key Words:source code; software security; static analysis
隨著軟件技術和網絡技術在各個行業的廣泛應用,以及以Linux操作系統為標志的自由軟件的大量存在和應用,人們面臨的軟件安全問題也日漸增多。研究表明,相當數量的安全問題都是由于軟件自身存著的安全漏洞引起的,惡意的攻擊者利用這些安全漏洞提升權限,訪問未授權資源,甚至破壞敏感數據,從而造成重大損失,近期發生的Struts2安全事件和OpenSSL出現“Heartbleed”安全漏洞均造成了很大影響。存在于計算機系統中的軟件安全漏洞已經成為信息安全的一個核心問題。
1 國內外研究現狀
目前,對于軟件的安全性分析挖掘,以美國為代表的信息化發達國家已經全面起步:美國國土安全部作為美國風險評估的領路者,擁有龐大的研究力量,幾乎影響著全世界在風險評估領域的概念、觀念和理念。上個世紀90年代末,美國開始把風險評估的范疇延伸到軟件源代碼上,在政府、學術界和產業界開展源碼安全分析與同源性測試。2004年由國土安全部主持了兩個大型安全項目DETER和EMIST,用以建設軟件安全測試床,開發科學、嚴格的攻擊和預防機制,研究軟件安全測試評估框架和方法,實施軟件漏洞分析與風險評估工作。2005年,美國總統信息技術咨詢委員會關于信息安全的年度報告中指出,美國政府部門和軍方等敏感部門使用的軟件產品,必須加強漏洞分析和風險評估,尤其提到這些軟件產品應進行源碼安全分析測評。在美國國土安全部的資助下,NIST設立了軟件保證度量和工具測量項目(Software Assurance Metrics And Tool Evaluation,SAMATE),其核心就是對軟件安全性進行分析研究。為了減少開源軟件的源碼缺陷,2006年初美國國土安全部設立了一個長期的開源軟件源代碼安全測試計劃,對包含Linux等在內的1750多萬行開源軟件的源代碼進行缺陷測試,以有力地保障這些軟件的安全性。在企業界,包括微軟、AT&T、Dell、Oracle、蘋果等世界知名軟件公司都已經或正在部署軟件源代碼安全性檢測系統。此外,微軟公司還提出了安全開發生命周期(SDL)的概念,將安全開發貫穿軟件生命周期的整個過程。它的基本原則是:安全的設計、安全的開發、安全的部署,通過SDL可以在很大程度上降低軟件安全風險[1-3]。
而國內對軟件的安全性檢查和驗證研究,還比較少,關于源代碼的靜態分析工具的研制應用主要是致力于某類缺陷的檢測,沒有集成的環境進行支撐。因此,開展C/C++源代碼的檢測技術的集成研究和工具化勢在必行[4-5]。
2 關鍵技術
C/C++源代碼靜態分析中主要涉及的關鍵技術包括:C++源代碼解析、路徑敏感的過程間遍歷算法的設計以及狀態緩存機制等。
(1)使用GCC作為源代碼解析的工具,由GCC負責進行源代碼的詞法語法分析與CFG生成。
(2)使用基于變量安全狀態跟蹤的模型進行C/C++的漏洞的檢測。一般而言,是指:使用基于有限狀態機的漏洞狀態機描述程序變量安全狀態的轉換規則;檢測工具對程序各可能執行路徑進行路徑敏感的過程間的靜態遍歷并識別當前操作;對當前操作所涉及的程序變量根據狀態機賦予其對應的安全狀態。在檢查點處,檢測工具檢測相關操作數據是否具有期望的安全狀態,若出現與期望安全狀態不符的情況,則表示發現了一個可能的安全漏洞。
(3)路徑敏感的過程間遍歷算法的設計。路徑敏感的遍歷是指根據代碼實際的可能執行路徑的遍歷,而不是直接按照源代碼自上而下的遍歷。過程間的遍歷是指當遍歷遇到一個用戶定義的函數時,能夠進入該函數,處理完該函數之后返回到調用點繼續遍歷。路徑敏感和過程間的遍歷是提高靜態分析精確度、減少漏報和誤報的有效手段。
(4)狀態緩存機制,基本塊層面的基于歷史狀態檢測的方法在過程內檢測中能夠很好的處理不同路徑上狀態一致以及循環停止的問題,但是在過程間檢測中就可能出現問題。應該以歷史狀態為基礎,針對過程間分析進一步完善緩存機制。
(5)采用一種基于內存模擬的方法實現別名分析。具體的說,就是為每個對象(指針變量)分配一個內存區域,該區域中保存該對象的狀態、字段等信息;如果兩個對象互為別名,就讓這兩個對象指向同一個內存區域。
3 系統概述
C/C++源代碼安全檢測系統適用于任何行業軟件C/C++源代碼的檢測工作,它為用戶的主機應用系統和基于WEB網站的業務系統提供全方位的基于源代碼的安全審計。在裝備類軟件、金融、政府等大型復雜應用系統的軟件開發、測試等階段,均可使用該系統進行源代碼審計工作,包括如下的內容:源代碼的缺陷和錯誤檢查;分析并找到缺陷、錯誤引發的安全漏洞,提供代碼修訂措施和建議,幫助用戶節約開發成本,最大程度地保證了系統的健壯性,輔助軟件企業提升生產效率。
C/C++源代碼安全檢測系統的分析過程采用C/S架構,分析結果的展示以B/S架構來實現。能夠與各類開發環境相集成。源代碼解析為基礎,缺陷分析為核心,結果構建為手段,人機界面、項目管理、擴展接口為支撐和輔助,系統架構如圖1所示。
4 功能設計與實現
整個C/C++源代碼缺陷分析系統要實現如下子模塊。(如表1)
4.1 源代碼解析模塊的實現
基于源代碼的靜態代碼分析技術對于編譯技術的借鑒主要集中在編譯前端部分,即在詞法分析和語法分析環節。考慮到本模塊要處理的C/C++涵蓋Visual C++和GNU C++兩個平臺,因此設計實現一個常規的能同時覆蓋兩個平臺的C++編譯前端。
源代碼預處理的流程如圖2所示。
經過源代碼預處理之后,不管是VC++項目源文件還是GCC/G++項目源文件,都通過GCC前端進行解析,生成CFG以及中間表示形式等數據結構。圖3展示了一個由gcc生成的CFG的示例:
4.2 缺陷分析模塊的實現
C/C++源代碼靜態分析系統的缺陷分析由兩部分組成:基于語義的缺陷分析和基于控制流的缺陷分析。其中基于語義的缺陷分析對變量未使用、函數未使用、變量未初始、類型轉換化以及C/C++特性相關的三種缺陷(關鍵性變量被聲明為公共的、關鍵性公共域缺乏適當的析構處理、異常處理中缺乏一般化例外的捕獲)進行檢測;基于控制流的缺陷分析對內存泄露、兩次釋放、釋放后再使用、返回空值、空指針引用、資源未釋放、競爭條件、拒絕服務、格式化字符串、整數溢出、死代碼、以及堆棧溢出、數組訪問越界等缺陷的檢測。
類型轉換雖然也屬于基于語義的缺陷分析,卻是在構造CFG完成的基礎上,遍歷CFG中的語句,根據一定的配置規則進行檢測的;其余的基于語義的缺陷分析均是利用解析前端實現的。
在基于控制流的缺陷分析中,我們進一步將缺陷細分為基于控制流的安全狀態跟蹤(包括內存泄露、競爭條件等7種缺陷)、基于數據流的污點傳播跟蹤檢測(拒絕服務、格式化字符串、整數溢出)、死代碼、基于數據流的安全狀態跟蹤(堆棧溢出、數組越界訪問)。
基于數據流的污點傳播跟蹤檢測是首先確定污點數據源,如從網絡、文件、用戶輸入等讀取數據的方法,將接受所獲取的臟數據的變量標記為Signed,然后根據控制流進行污點傳播,在檢查點處判斷相關變量是否保持Signed狀態,如果是,這報告一個相應的缺陷。數據源函數、傳播函數、檢查點函數等從檢測規則集中獲取。具體的檢測流程如圖4所示。
死代碼的檢測是利用約束求解技術,判斷對于每條路徑都不可行的代碼塊,這些代碼塊即被認定為死代碼。
基于數據流的安全狀態跟蹤(堆棧溢出、數組越界訪問)檢測技術與死代碼的檢測具有相關性,都是使用約束求解技術。所不同的是,死代碼是根據已有的路徑條件判斷新遇到的路徑條件是否可行,而堆棧溢出和數組越界訪問則是利用路徑條件判斷檢查點處的各相關變量之間的關系是否滿足所定義的規則,然后根據規則確定是否存在缺陷。在遍歷方式,死代碼使用了非路徑敏感的流敏感遍歷方式,而堆棧溢出的檢測是路徑敏感的遍歷方式;同時,死代碼無需外部規則,堆棧溢出需要規則定義數據流向、緩沖區的改變以及檢查點的設置等。
4.3 結果輸出模塊實現
結果輸出模塊與缺陷分析模塊進行交互,當缺陷分析模塊發現源代碼中的缺陷時會調用本模塊保存分析結果。保存結果應包含缺陷涉及的變量、缺陷的完整觸發路徑、數據傳播途徑、缺陷位置、缺陷類型(以上均可以從變量信息中獲得)、缺陷描述、可能的修補手段及危險級別等信息(后面這三項內容從XML規則文檔中提取)。
4.4 項目管理模塊實現
對被測源碼按照項目進行管理,提供項目配置功能,包括源碼分析范圍,分析級別、分析缺陷類型定制等。提供項目結果輸出配置,包括輸出缺陷類型、級別、輸出形式等。
4.5 人機界面模塊實現
提供可視化界面,便于用戶進行操作。
4.6 擴展接口模塊實現
支持與主流開發環境的集成,如windows平臺上的VS系列、中標麒麟平臺上的Eclipse和QT等。
5 結語
C/C++源代碼安全檢測系統現在已經可以在傳統的X86平臺下運行使用,目前正在向國產化軟件平臺進行移植。后期還需要開展的工作包括:與中標麒麟操作系統進行適配、與國產硬件平臺進行適配優化和對核心源碼分析模塊進行重構等。
參考文獻
[1]EVANS D,LAROCHELLE D.Improving security using extensible light-weight static analysis[J].IEEE Software, 2002,19(1):42-51.
[2]BRIAN C. Static analysis for security[J].IEEE Security & Privacy,2004,7(4):32-36.
[3]Institute ANS. ISO programming language C++[S].2003.
[4]李曉南,范明鈺,王光衛.基于靜態檢測工具的源代碼安全缺陷檢測技術[J].計算機應用研究,2011,28 (8):2997-2998.
[5]林銳,韓永泉.高質量程序設計指南—C/C++語言[M].北京電子工業出版社,2008:240-247.