999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于Clang編譯前端的Android源代碼靜態分析技術①

2017-10-20 03:08:02曹原野丁麗萍
計算機系統應用 2017年10期
關鍵詞:分析檢測

曹原野 ,丁麗萍

1(中國科學院 軟件研究所 基礎軟件實驗室,北京 100190)2(中國科學院大學,北京 100049)

基于Clang編譯前端的Android源代碼靜態分析技術①

曹原野1,2,丁麗萍1

1(中國科學院 軟件研究所 基礎軟件實驗室,北京 100190)2(中國科學院大學,北京 100049)

Android手機在全球占有很大的市場份額,基于Android衍生的第三方系統也為數不少.針對Android系統重大安全問題頻發的現狀,提出一種使用Clang編譯前端對Android源碼進行靜態分析的方法.該方法從已公布的CVE漏洞中提取規則和模型,通過改進的Clang編譯前端,對Android源碼進行靜態分析,從而檢測出有潛在安全風險的代碼片段.在對Android源碼進行污點分析時,調用新加入的stp約束求解器,通過符號執行,對敏感數據進行污點標記,并對敏感函數、敏感操作、敏感規則進行污點分析,如果存在潛在的安全隱患,則進行報告.經過實驗分析,該方法可以找出Android源代碼中存在的同類型有安全風險的代碼片段,可以檢出libstagefright模塊5個高危CVE漏洞.

Clang 編譯器; 安卓; 靜態分析; 污點分析; 符號執行

1 引言 111

Android系統因其開源性和開放性,在智能手機市場占有很大的市場份額.近些年來,Android系統不斷發展,在智能家電、物聯網等領域迅速攻占市場,與人們的日常生活越來越緊密相關.然而,Android系統的安全問題日益突出,不斷爆出影響極大的安全漏洞,不僅影響了用戶的使用體驗,更嚴重威脅到了用戶的隱私,例如:具備麥克風或攝像頭的Android智能電視被遠程控制,將會造成非常可怕的隱私泄露.因此,Android硬件廠商在硬件發布之前,非常有必要對定制的Android系統進行安全審計,以盡可能地減少潛在的安全隱患.對定制的Android源代碼進行安全審計在保護用戶的隱私、減少企業的開發成本方面有重要意義.

在研究Android源代碼的CVE(Common vulnerabilities and exposures)漏洞補丁的過程中,發現部分漏洞存在特定的規律和模式.本文對這些規律和模式進行了總結分析,提出了一種基于改進的Clang編譯前端進行安全分析的靜態檢測方法,該方法通過Clang編譯前端對指定的Android模塊進行符號執行[1,2],通過污點傳播對敏感數據進行標記,通過對特定的函數[3,4]、條件分支、語法結構進行污點分析,找到有潛在安全風險的代碼片段,并給出相應的檢查報告.企業在對Android系統進行定制修改之后,如果能夠在系統發布之前,對Android定制系統的源代碼進行安全審計,則可以有效降低定制系統的安全風險所帶來的損失[5],同時因為審計的自動化,也可以大幅降低人力成本.

2 相關研究

代碼審計的最終目標是挖掘軟件中潛在的有安全風險的漏洞代碼.目前,針對Android系統的漏洞挖掘已經有很多成熟的方法.例如:人工審查、模糊測試、動態分析、靜態分析等方法.

人工審查就是通過人工閱讀代碼的方式對源代碼進行逐行逐行地分析,判斷是否有安全問題.這要求審查人員有相當深厚的審查經驗,而且很費時間,適用于簡短但是易錯的代碼,如驅動代碼.

模糊測試(Fuzz)是指通過給目標接口輸入大量的隨機數據,來測試接口是否能夠正常處理這些畸形數據的測試方法.如果接口或系統出現了異常,則認為接口極有可能存在缺陷.模糊測試的優點是簡單有效,但是相當耗費時間,因為是隨機生成的數據,所以具有一定的概率性.而且測試速率要受制于目標接口的響應速率.對應的工具有Peach等.Peach是一個遵守MIT開源許可證的模糊測試框架,用戶通過編寫Peach Pit配置文件,可以定義Fuzz過程的配置和原始數據結構的定義.通過定義原始數據結構生成結構化的部分隨機數據,來實現精確的模糊測試.

動態分析是指對二進制程序進行插樁,來達到運行時對程序的控制和監控.動態分析的優點是準確率高,覆蓋面大,但是缺點是依賴于運行平臺,有路徑爆炸的風險,并且在編譯過程中損失了一些代碼的細節信息.對應的工具有 Pin、KLEE、Android_S2E[20]等.Pin是Intel公司提供的二進制插樁工具[6],它允許在可執行程序的任何地方插入任意代碼[7].KLEE是一款源代碼動態符號執行工具.KLEE需要修改源代碼,通過對源代碼內特定的輸入數據進行標記,插入自己的符號執行代碼,然后編譯執行并收集變量信息.Android_S2E是一款全系統符號執行工具,它預裝QEMU模擬器和KLEE在虛擬機上運行Android,并執行符號執行,可以遍歷Android系統上小型C語言程序的所有路徑.

靜態分析是指在不運行代碼的情況下,通過多種方式對源代碼進行分析之后,得出源代碼是否存在問題的結論.分析方法涵蓋簡單的正則、詞法分析、語法分析、上下文路徑敏感分析等.對應的工具有Coverity、Clang等.Coverity是一個先進的、可配置的用于檢測軟件缺陷和安全隱患的靜態代碼分析解決方案,它能自動化地檢測和解決C、C++、Java、C#源代碼中多種類型的缺陷,Coverity對Android系統有針對性優化,但是Coverity是收費且閉源的.Clang是LLVM開源編譯套件的一個編譯前端,負責將C、C++、Object-C源代碼翻譯為中間代碼[8,9],而且Clang自身具備靜態分析的能力,可以在不運行代碼的情況下對代碼進行編譯分析.

現有Android系統安全問題的文獻研究多數集中在Android應用層上的研究.對于Android系統自身底層代碼的安全研究的文獻研究其實不常見[10,11].移動安全會議上提到的工業界常用的方法多集中于模糊測試的方法.使用模糊測試的方法雖然具有一定的隨機性,但是簡單便捷,并且短期內容易看到成效.但是,安全研究員如果想要建立一種長效的安全機制,這種機制是穩定的,而且可以逐步完善、逐步歸納吸收已有的安全風險的話,使用靜態分析是一種非常合適的方案.

靜態分析沒有模糊測試的隨機性,分析結果比較穩定.并且,通過對現有的安全風險進行歸納吸收,可以不斷完善靜態分析工具,那么靜態分析工具就能夠在檢測能力上得到持續加強.而一款能夠持續加強的靜態分析工具必須是開源的,所以本文主要調研了Clang編譯前端對Android源代碼進行靜態分析的難點.

本文經過調研,使用Clang成功對Android源代碼進行了分析,并主要克服了 3個方面的困難.1)新版的Clang 3.8無法直接對Android源代碼進行分析,需要做兼容處理.2)Clang自帶的約束求解器的求解能力過弱,不適合應用在Android源代碼這種復雜項目上.3)Clang自帶的檢測規則是通用檢測規則,沒有針對Android源代碼的檢測規則,導致檢測能力過弱.

本文克服了上述3個困難,最終實現了目標:實現一種工業界可用的,基于改進的Clang編譯前端的,用于Android系統源代碼的靜態分析方法.

3 基于Clang編譯前端的靜態分析原理

Clang作為LLVM編譯套件的編譯前端,自帶一個靜態代碼分析工具,可以編譯分析C、C++、Object-C源代碼,此靜態分析工具屬于Clang的一部分因而完全開源.

Clang在對源代碼進行編譯的時候,會通過靜態分析,對代碼風格、語法錯誤和潛在的風險進行warning警告.Clang靜態分析器通過自定義代碼可以實現更復雜的檢測機制來進行靜態分析.Clang的靜態分析器首先通過程序代碼,生成AST(語法樹),然后根據AST生成 CFG(控制流圖),通過符號執行生成擴展圖(ExplodedGraph),具體控制流程如圖1[12]所示.

圖1 Clang 的靜態分析過程

通過自定義Checker(Clang中的檢查器,用來檢測自定義缺陷),可以實現對AST和ExplodedGraph的分析和控制.Checker不僅僅只能是被動的調用,Checker也能主動地修改ExplodedGraph.如果Checker認為存在特定的缺陷,就可以調用BugReport來報告存在的缺陷,方便測試人員可視化地觀察檢測信息.

Clang的AST樹近似于常規的編程語法結構.通過“clang-Xclang-ast-dump example.cpp”可以對源代碼生成的AST進行觀察.AST語法樹主要由兩類結點(Stmt與Decl)和派生自他們的子結點構成.Stmt是指statement語句,Decl是指 declarations聲明.

Clang的CFG控制流圖由若干個CFGBlock塊組成,每個CFGBlock均包含有EXIT塊和ENTRY塊.并且每個CFGBlock塊由一組CFGElement組成,其中的CFGElement代表AST樹中的一個結點.

Clang的ExplodedGraph圖是在通過符號執行遍歷CFG圖的時候產生的.ExplodedGraph中的每個結點,都包含了 ProgramPoint點和 State 信息.Program-Point點,用來定義源代碼運行到該點時所有變量的值.State信息用來表示源代碼在符號執行過程中的狀態信息,包括:表達式到值的映射關系、各種變量到值的映射關系、路徑條件約束等信息.

通過Clang的源碼,可以發現,如果將Clang的靜態分析直接應用到Android系統源碼之上,基本沒有效果.一個原因是Clang自帶的range約束求解器的求解能力過于薄弱,只能處理簡單約束.另一個原因是Clang作為一個通用編譯前端,更注重的是通用性,所以特定問題的檢測能力不強.需要對Clang的符號執行能力和檢測能力進行增強.所以,以下小節將逐個描述對Clang進行加強的實現原理.

3.1 改進Clang靜態分析Android源碼的兼容性

Android源碼內,含有LLVM的預編譯工具鏈,但是直到最新的Android7.1的源代碼,LLVM預編譯工具鏈中Clang的版本仍舊是3.3版本.本文需要定制較新的Clang3.8版本進行靜態分析.所以需要了解Clang靜態分析指令和Android源代碼的編譯腳本工作原理.

Clang靜態分析由兩個指令構成,分別是“scanbuild”和“scan-view”命令.“scan-build”命令后面緊接著正常的編譯命令,例如“scan-build g++ example.cpp”或者“scan-build make-j4”這種編譯命令.其中“scan-build”命令會對后面的編譯命令進行分析,替換其中的編譯器為Clang本身,則Clang可以順利地進行靜態分析.“scan-build”在分析完畢之后,會留下一個特殊的目錄,使用“scan-view”打開這個目錄,則可以顯示分析報表.

Android源代碼的編譯腳本主要集中在源代碼根目錄的build/envsetup.sh文件里.其中主要有4個編譯命令,分別是 mmm、mm、m、make 命令.mmm 命令主要用于編譯指定路徑下的模塊,mm命令用于編譯當前路徑下的模塊,m命令編譯當前目錄下的所有模塊,make命令則是編譯整個Android系統.為了靜態分析的需要,主要進行單個模塊的分析,所以選用mmm命令.通過更換mmm命令后的路徑,可以實現不同模塊的靜態分析.“mmm path-B”其中的“-B”參數則是無論源碼修改與否都強制編譯path目錄下的所有源碼.

直接使用“scan-build mmm path-B”則會直接報錯.通過研究envsetup.sh的代碼,發現在getdriver函數聲明了靜態分析的使用規則和“scan-build”的二進制路徑,將getdriver函數的“scan-build”路徑改為改進的Clang源代碼生成的“scan-build”路徑.同時執行“WITH_STATIC_ANALYZER=1 mmm path-B”則可成功啟動改進Clang的靜態分析.但是,分析途中一定會出錯,因為高版本的Clang已經不支持一些舊命令參數,所以需要對“scan-build”編譯腳本調用的其他編譯腳本進行兼容修改.經過修改的的編譯腳本可以正確對某個模塊進行靜態分析.

3.2 增強Clang的符號執行能力

SMT(Satisfiability modulo theories)可以用來解決邏輯公式的決策問題[13],可以用來處理布爾運算、量詞、算術運算、比較運算、位運算等約束性求解問題.SMT模型有一些具體的約束求解器實現,例如:z3約束求解器、stp約束求解器等.這些求解器具備強大的求解能力,可以處理編程語言中常見的復雜條件判斷、位運算、數組操作等.

符號執行是CFG生成ExplodedGraph時使用的.Clang靜態分析程序讀取CFG,當遇到條件分支時,會根據不同的條件分支,依次執行不同的條件分支.在執行不同的條件分支之前,符號執行會把進去當前分支所需要的條件放入約束求解器查詢,如果當前條件滿足約束求解器,則執行分支并把分支條件放入約束求解器,否則不執行當前分支.

Clang具備符號執行的能力,但是其自帶的range約束求解器能力不強,只支持簡單約束條件,遇到多元約束條件不能處理則忽略,這大大削弱了符號執行的準確性.在實際的復雜代碼中,這個自帶的約束求解器在精度方面經常不能滿足預想的要求.

但是Clang本身支持約束求解器的擴展,可以通過仿照range約束求解器的編寫方式,修改Clang配置文件,增加新的約束求解器,達到增強約束求解器的目的.

本文通過修改Clang源碼,加入了stp約束求解器,使Clang可以處理復雜的多元約束求解.通過增強Clang符號執行的約束求解能力,提高其檢測精度.

3.3 增強Clang的靜態檢測能力

作為一款通用編譯前端,Clang所面對的是通用場景的代碼.其靜態分析里的檢測規則面向的是常見的缺陷問題.所以,Clang對于特殊模式的問題無法進行正確檢測而得出結果.于是,在使用Clang對Android的源碼進行分析之前,需要預先增強Clang的靜態檢測能力.

對于Android系統,如果Clang想要檢測出安全風險,就需要預先知道可能的攻擊面.Android系統因為豐富的交互功能,其本身具有很多潛在的攻擊面.攻擊面可以分為 4 類.1)遠程攻擊面:主要包含了網絡協議棧、對外暴露的網絡服務、短信、彩信、基礎軟件(瀏覽器接口、多媒體和文檔處理、電子郵件)等.2)物理相鄰的攻擊面:無線、藍牙、NFC 等.3)本地攻擊面:文件系統、系統調用等.4)物理連接攻擊面:USB連接等.

可被用戶控制的數據從這些攻擊面,流入到系統的控制流中,如果處理不當,則可能會引入安全風險.所以,靜態分析的主要目標,就是需要頻繁從攻擊面獲取數據的模塊,例如:libstagefright模塊.為此,需要設定一段污點傳播程序,對Android源碼中有可能從攻擊面引入的危險數據加上污點標記.并對污染的數據進行污點傳播,即圖2的“敏感函數污點標記”.敏感函數例如:內存操作函數、網絡操作函數、緩沖區管理函數、文件管理函數等.

圖2 增強的靜態檢測邏輯

在Android源代碼里,充滿了大量的宏定義和復雜的工具類,給開發人員帶來了巨大的便利,但是也給開發人員帶來了困擾:有時候會不記得當前的變量到底是什么類型,有時候會忘記一些必須的操作.以下總結一些在Android源代碼漏洞中常見的錯誤模式.

(1)敏感函數的參數錯誤

memcpy(dest,src,len);

在復雜邏輯中,開發人員可能會忽略對len的正確約束,導致len可以賦值為一個超大的整數值.

(2)隱式轉換

memcpy(dest,src,len);

在開發中,開發人員混淆了len的類型,直接將有符號數直接傳入參數,同時沒有限制len必須大于等于0.

long long a = int_b + int_c + (long long)d;

在開發中,遇到一個復雜計算式,而且數據類型不一致時,開發人員意識到需要進行強制類型轉換.但是強制類型轉換過晚,int_b和int_c已經發生了溢出并進行了隱式轉換之后,才與d變量進行相加.

(3)分支條件

if(int_e+100

在開發中,開發人員忘記int_e的范圍沒有進行約束,有可能發生溢出.

if(int_j < uint_k)

在開發中,開發人員忘記int_j的類型,且沒有約束int_j必須大于等于0.

為了對上述3種錯誤模式進行追蹤檢查,要預先設定鉤子函數進行捕獲,當鉤子函數捕捉到其中之一的模式正在發生,且包含有污點數據的時候,啟動進一步分析.例如:內存分配函數、變量隱式轉換、條件判斷表達式這三種情況.這三種情況依次對應圖2中的“敏感函數污點分析”,“污點數據類型轉換”,“分支條件判斷污點”.啟動進一步分析之后,對應到圖2中的“溢出判斷”和“規則判斷”.

“溢出判斷”是指通過獲取污點變量的取值范圍[14,15],判斷是否存在于合法的區間.首先,通過Clang獲取污點變量的類型,根據變量類型生成對應的最大值和最小值.通過stp約束求解器的查詢功能,查詢污點變量是否能夠取到最大值的同時再取到最小值,如果可以同時取到,則認為存在風險.

“規則判斷”是指通過設定若干組語法樹規則,對含有污點數據的語法樹進行匹配判斷.例如:當發現污點數據在二元算式之后發生了類型提升,而且是隱式類型提升的時候,說明在編程語法上存在安全風險,此時可提示有潛在的安全風險.

4 Android 源碼靜態分析的實現

4.1 對Android源代碼的修改

建立Android源代碼的本地mirror,從mirror拉取branch為android-5.1.1_r14(為了進行對比實驗,需要拉取若干個branch)的分支,安裝好編譯工具,配置Android5.1.1的編譯環境和二進制輸出目錄,進入Android代碼目錄,執行代碼1的指令.

代碼1.編譯所有Android源代碼$ source build/envsetup.sh$ lunch aosp_arm-eng$ make -j4

在靜態分析之前,必須先整體編譯一次Android,因為一個模塊在編譯的時候經常會依賴其他模塊,如果在靜態分析前先全部編譯一次,就不會出現找不到依賴模塊的情況.

Android整體編譯完成之后,在Android的源代碼目錄下編輯build/envsetup.sh下按照代碼2進行編輯.修改--use-analyzer參數后面的路徑,更新為修改過的Clang程序的二進制文件.

Android源代碼的工具鏈自帶了一套Clang3.3編譯前端,但是其版本太低,需要如代碼 3 里所示,修改/prebuilts/misc/linux-x86/analyzer/bin/ccc-analyzer文件,做下列兼容工作,否則改進的Clang3.8無法正常運行.其主要操作是:通過參數指定Clang3.8使用新加入的stp約束求解器,并且替換一些傳遞的過時的命令行參數.

?

push @Args,“-Xclang”,“-analyzer-viz-egraph-ubigraph”;}+ //強制Clang編譯器使用本實驗新加入的stp求解器+ push @Args,“-Xanalyzer”,“-analyzer-constraints=stp”; my$AnalysisArgs = GetCCArgs(“--analyze”,@Args); @CmdArgs =@$AnalysisArgs;+ //對參數進行修改,以適應新的Clang編譯器+ my @NewCmdArgs;+ foreach my $one (@CmdArgs){+ if($one eq “-Qignore-c-std-not-allowed-with-cplusplus”+ || $one eq “-fobjc-default-synthesize-properties”+ || $one eq “-fno-cxx-missing-return-semantics”)+ {next;}+ if($one eq “-disable-global-ctor-const-promotion”){+ push(@NewCmdArgs,“-disable-cgp-ext-ld-promotion”);+ next;+ }

$one);+ @CmdArgs = @NewCmdArgs;

代碼4.替換新的Clang編譯前端if($pid == 0){ close FROM_CHILD; open(STDOUT,“>&”,*TO_PARENT); open(STDERR,“>&”,*TO_PARENT);+ //置為實驗修改的Clang的二進制的地址+ $Cmd = “xxx”;exec $Cmd,@CmdArgs; }

再如代碼4所示,修改/prebuilts/misc/linux-x86/analyzer/bin/ccc-analyzer文件,修改內部使用的$Cmd變量.從而完成對 Android 源碼的修改.此時,已經可以使用Clang3.8正常編譯分析Android系統源代碼.

4.2 添加stp約束求解器

首先,安裝 stp約束求解庫,需要安裝 minisat庫和 stp 庫.然后,進入 llvm 源碼,在 tools/clang/lib/Static-Analyzer/Core/目錄下仿照現有的RangeConstraint-Manager.cpp編寫調用stp求解器的STPConstraint-Manager.cpp,并對外提供接口CreateSTPConstraint-Manager返回STPConstraintManager類的實例供靜態分析核心使用.

STPConstraintManager.cpp可以參考網絡上已有的樣例約束求解器代碼進行修改,但是需要注意因為本文使用的Clang是新版的,必須注意代碼的兼容性問題(過時的接口、類或結構體的成員的變動),否則程序無法正常執行.

最后,如代碼 5 所示,在 tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def中加入如下一行聲明(注意要和STPConstraintManager類的接口Create-STPConstraintManager名稱相同),可以支持在命令行選擇實際使用的求解器(range求解器或者stp求解器),方便進行對比實驗分析.

代碼5.增加新的約束求解器ANALYSIS_CONSTRAINTS(STPConstraints,“stp”,“Use STP solver”,CreateSTPConstraintManager)

4.3 改進Clang的Checker

如圖1所示,Clang編譯前端在靜態分析中,真正執行缺陷判斷的是一系列的Checker.所以,為了增強Clang的靜態檢測能力,必須對Clang的一系列的Checker進行增強.

污點傳播部分,修改LLVM代碼里的toolsclanglibStaticAnalyzerCheckersGenericTaintChecker.cpp.這個Checker支持對C的函數進行污點標記和傳播,但是不支持對C++類的處理.對這個Checker進行增強,加入對C++類的判斷和處理.

因為Android系統代碼的復雜性,系統代碼對相當一部分的文件和內存操作都進行了封裝.在對C++的成員方法進行分析時,可以對參數或者返回值進行污點標注.在實際標注的時候可以根據待分析代碼的具體特征(例如:通用buffer緩沖類,及其他文件操作、內存操作的通用類)添加特定處理,來進行污點設定.開啟 (默認 C l a n g不開啟)這個修改過的Checker即可實現數據的污點標記.

“敏感函數污點分析”部分可以通過表1中check::CheckPreCall搶在函數調用之前,進行分析.“污點數據類型轉換”可以通過check::CheckPreStmt進行攔截判斷,通過對Expr的判斷,抽取其中的隱式轉換和顯式轉換,進行分析.“分支條件判斷污點”可以通過check::CheckBranchCondition對條件分支進行攔截,并對其中的Stmt進行判斷.

表1 Clang 的路徑敏感分析接口

圖2中的“溢出判斷”可以通過Clang內置的SValBuilder類的evalBinOpNN方法對污點變量的范圍進行估計,測試污點變量是否經過正確約束.

圖2中的“規則判斷”則可以通過ASTContext類的getParents(node)方法獲取父節點,或者通過node本身自帶的各種方法獲取其子結點.甚至可以使用Clang內置的RecursiveASTVisitor類實現對某個結點的子結點進行自動遞歸查詢.

4.4 漏洞代碼的特征分析及處理

代碼6展示了CVE-2015-1538的部分補丁.

代碼6.CVE-2015-1538部分補丁代碼mTimeToSampleCount = U32_AT(&header[4]);- uint64_t allocSize = mTimeToSampleCount * 2 * sizeof(uint32_t);+ uint64_t allocSize = mTimeToSampleCount * 2 *(uint64_t)sizeof(uint32_t);

代碼6中的缺陷存在著固定的模式:污點數據由uint32類型參與運算提升為uint64類型,但程序員沒有意識到溢出發生在類型的隱式轉換之前.所以引入了潛在的溢出風險,故補丁加入了強制轉換.

但是,代碼6里的補丁仍舊是錯誤的!這導致了后序的漏洞CVE-2015-6601.仔細觀察代碼6中的補丁,程序員的補丁里顯然意識到了污點數據隱式轉換的危險性,但是程序員忘記了計算是從左到右執行的.強制轉換太遲了,污點數據仍舊可以先溢出,再提升類型.

如代碼6所示,U32_AT是libstagefright從緩沖區讀取數據的公共方法,類似的還有U16_AT、U64_AT.U32_AT函數會觸發圖2中的“敏感函數污點標記”,使mTimeToSampleCount變量被標記.代碼6中對allocSize的賦值操作中,實際上發生了類型提升(未打補丁是隱式提升,打了錯誤的補丁是顯式提升).如果表達式中包含污點數據且存在類型提升,則Chekcer觸發圖2中的“污點數據類型轉換”會對其中的類型轉換進行檢查.

代碼7展示了CVE-2015-6604的部分補丁.

代碼7.CVE-2015-6604部分補丁代碼return false;}- if (offset + dataSize + 10 > mSize){+ if (dataSize > mSize-10- offset){return false;}

代碼7中的缺陷存在著固定的模式:在一個條件分支語句中,程序員忽視了污點數據的存在,過分相信變量,直接讓污點數據參與了計算,之后再參與比較判斷.

如代碼 7所示,其中 dataSize的數據,由 U32_AT方式獲取,故被標記為污點數據.但是在if條件判斷語句中,因為條件判斷表達式含有污點數據,故觸發圖2中的“分支條件判斷污點”,對條件表達式進行求值分析.

4.5 Clang的報告生成

在4.3章中使用Clang的Checker對待檢測代碼進行分析之后,如果發現潛在的問題,則使用Clang自帶的BugReport進行風險代碼的報告.通過定義一個自定義BugReport,可以實現特定格式內容的Bug報告.在分析結束之后,通過scan-view命令打開分析報告網頁,對分析結果進行查看.

5 實驗及結果分析

5.1 試驗環境

本文使用 Ubuntu16.04 LTS X64 操作系統,處理器 Intel酷睿 i7 4750HQ(3.2 GHz),16 GB 內存,80 GB交換分區,1000 GB 機械硬盤.基于 Clang3.8 進行測試修改.靜態分析期間,不同時運行其他程序,以免影響時間和內存使用的實驗結果.

Clang運行參數方面,除了第3章節所做的代碼修改和實驗過程中輸入的動態參數,其余配置保持默認參數不變.因為符號執行會出現路徑爆炸問題,Clang會使用一個默認最大循環執行次數來進行限制,默認值是4,本實驗不修改.

5.2 使用測試集對改進后的Clang進行驗證

經過改進的Clang不能直接用于Android系統的代碼分析,需要首先確保修改的正確性,保證改進后的Clang編譯前端本身沒有邏輯錯誤.一個錯誤的Clang編譯前端在分析Android源代碼時的結果是不可信的.而改進的Clang編譯前端的代碼修改集中在符號執行和整形溢出檢測上,所以需要一組整形溢出測試集驗證Clang的符號執行精度和整形溢出檢測能力.

測試集的選取,選用的是從NIST網站下載的美國 NSA (National security agency)開發的 Juliet_Test_Suite[24]測試集.Juliet_Test_Suite 測試集包含多種CWE (Common weakness enumeration)[16]類型的常見漏洞代碼.本實驗選取其中的“CWE190_Integer_Overflow”測試集.其測試集下總共有5種類型的子測試集,分別編號 S01,S02,S03,S04,S05.

通過特定的宏定義,可以調整測試集的檢測特性.如:只檢測存在有安全缺陷的函數、只檢測不存在安全缺陷的函數、檢測全部函數.表2顯示了5個子測試集的函數用例數量.

表2 測試集溢出漏洞用例數量 (個)

測試過程中,采用子測試集逐個進行測試的方式執行.單個子測試集在測試的時候,分為六次測試.前兩次使用未修改的原生的Clang且使用自帶的range約束求解器分別測試安全函數和不安全函數.中間兩次使用改進的Clang且使用自帶的range約束求解器分別測試安全函數和不安全函數,后兩次使用改進的Clang且使用新加入的stp約束求解器分別測試安全函數和不安全函數.運行靜態分析的時候,記錄分析所需要的時間,并分析所得到的結果,測試所需時間如表3所示.其中,good_origin_range 指原生的 Clang 使用自帶的range求解器只檢測安全函數,good_improved_range指改進的Clang使用自帶的range求解器只檢測安全函數,good_improved_stp指改進的Clang使用新加入的stp求解器只檢測安全函數.bad_origin_range,bad_improved_range,bad_improved_stp 指相同的情況下只檢測不安全函數.

表3 靜態分析所需時間 (秒)

通過表3分析發現,不管是只檢測安全函數還是只檢測不安全函數,在都使用自帶的range求解器的情況下,改進的Clang比原生的Clang檢測時間增長了約兩倍,這是因為改進的Clang增加了污點傳播等更多的檢測規則,導致檢測時間的增大.同樣是改進的Clang,使用新增加的stp求解器比使用range求解器耗費的時間都要多,但是基本不多于10%,這是因為stp的求解能力更強,規則更復雜,導致了耗費時間的增加.

表4 中“good_origin_range”和“bad_origin_range”分別指原生Clang使用自帶的range求解器測試安全用例和不安全用例的情況.通過測試發現,基本只能找到“Dead assignment”,“Dead initialization”,“Memory leak”這三種錯誤.不管是安全測試用例還是不安全測試用例,均無法檢出任何溢出漏洞.這是因為原生的Clang本身無對應的檢測規則.

表4 檢出溢出類型漏洞數量 (個)

表4 中的“good_improved_range”和“good_improved_stp”分別指改進的Clang使用自帶range求解器或stp求解器分別對安全用例的檢測情況.改進的Clang,因為檢測規則的增加,已經可以檢測溢出漏洞.但是,安全測試用例中是沒有不安全的用例的.所以,通過比較,在使用 range求解器的情況下,有超高的誤報,而stp的誤報則是非常的低.具體原因是range求解器的能力過弱,很多復雜約束不能處理,導致實際上沒有成功加入約束條件,導致了大量的誤報.其中誤報的數量甚至超過了測試用例的數量,一個原因是某些用例有多種測試方法,此外如圖2所示,改進的Clang有3種觸發方式進行缺陷分析,一個函數由若干行的代碼構成,所以一個函數體可能檢出不少于1個漏洞.

不安全測試用例在源代碼的對應代碼行的注釋中,進行了標注.表4 中的“bad_improved_range”和“bad_improved_stp”分別指改進的Clang使用自帶range求解器或stp求解器分別對不安全用例的檢測情況.通過對測試報告的排查,stp求解器雖然檢出的結果比較少,但是非常準確.range求解器檢出的結果存在大量的誤報,將測試用例的源代碼中,沒有標記為缺陷位置的代碼檢測為存在缺陷.

收集測試用例的靜態分析結果,同時收集靜態分析日志,結合在一塊進行分析,可以得出結論:stp 求解器雖然在時間耗費上比range求解器稍多,但是在約束求解精度上,stp求解器有很大的提高; 同時結合靜態分析日志和測試用例源代碼,對比stp求解器的約束區間,可以發現求解器計算出了正確約束區間.

5.3 使用改進的Clang編譯前端對Android源碼進行分析

參考第4節的“Android代碼靜態分析的實現”里的實現,整個Android源代碼在編譯和修改完畢之后,運行代碼8里的指令,即可使用改進的Clang且使用stp約束求解器對Android源碼進行靜態分析.

代碼8.執行靜態分析$source build/envsetup.sh$lunch aosp_arm-eng$WITH_STATIC_ANALYZER=1 mmm model_path -B

本實驗主要通過“WITH_STATIC_ANALYZER=1 mmm frameworks/av/media/libstagefright/-B”對Android源代碼的libstagefright模塊進行分析.通過對Android不同版本的源碼進行靜態分析,對于未打補丁的源碼可以找出以下高危漏洞,其漏洞CVE編號分別如下:CVE-2015-1538,CVE-2016-6601,CVE2015-3832,CVE-2015-3831,CVE-2015-6604.

圖3 CVE-2015-1538 漏洞檢測結果界面

5.4 分析過程的時間復雜度、空間復雜度及優化

本實驗的分析工具在時間復雜度上耗時較大,分析簡單的libmedia模塊需要十幾分鐘,但是分析復雜的libstagefright模塊就需要幾十個小時.通過使用linux下的perf性能調優工具對分析過程(不能直接分析第5.3節中的mmm命令,分析mmm函數解析后的命令)進行分析,發現耗時的TOP-50函數均是來自libstp.so和libminisat.so里的函數,兩個庫文件里的函數總共占用了95%以上的運行時間.其中libstp.so是分析工具所依賴的STP求解器的庫文件,libminisat.so是libstp.so所依賴的庫文件.運行時間主要耗費在求解表達式.

本實驗的分析工具在空間復雜度上耗費也較大.如分析 libmedia 模塊需要 1–2 GB 內存,分析 libstagefright模塊需要 2–4 GB 內存,短時間會使用 16 GB 以上內存.通過使用linux下的gdb和valgrind內存分析工具對分析過程進行分析,主要發現libstp.so庫文件與加入的STP求解器代碼存在內存泄露問題,其中存在少數沒及時釋放的大內存塊,導致了大量的內存占用.

針對時間復雜度和空間復雜度的問題,對本實驗的分析工具進行對應的優化,在加入的STP求解器的代碼部分,加入了遺漏的釋放資源的代碼,降低內存占用,減少了部分內存泄露.同時對Checker里的檢測代碼進行優化,盡量用循環來取代遞歸,同時將符號執行里的污點數據按照符號執行地址存放在公共map數據結構里,進行加速,以此節約內存和時間.

6 結語

本文提出了使用改進的Clang對Android源代碼進行靜態分析的研究和實現,通過新增Clang的約束求解器并對靜態檢測功能進行改進,實現了對Android部分類型漏洞的靜態分析檢測,并成功檢測到部分漏洞.最終實現了可用的對Android源代碼進行分析檢測的實用靜態分析工具.

但是分析工具自身還存在一些問題,例如:時間耗費較長、內存耗費較大,經過第5.4節的優化,解決了部分問題,但是內存泄露問題沒有徹底去除,耗時仍舊偏長; 此外靜態分析自身的符號執行存在一定偏差,面對特別復雜的約束條件和調用過程,不能準確地進行約束求解.而且,圖2的“溢出判斷”中的判斷方法有些粗糙,容易造成漏報,“溢出判斷”需要對加減乘除等各種情況進行仔細地處理,這些處理需要大量的細節進行完善.

1Dietz W,Li P,Regehr J,et al.Understanding integer overflow in C/C++.ACM Trans.on Software Engineering and Methodology (TOSEM),2015,25(1):2.

2Bush WR,Pincus JD,Sielaff DJ.A static analyzer for finding dynamic programming errors.Software-Practice &Experience,2000,30(7):775–802.

3Schmidt D,Steffen B.Program analysis as model checking of abstract interpretations.International Static Analysis Symposium.Pisa,Italy.1998.351–380.

4Cadar C,Dunbar D,Engler D.KLEE:Unassisted and automatic generation of high-coverage tests for complex systems programs.Proc.of the 8th USENIX Conference on Operating Systems Design and Implementation.San Diego,California,USA.2008.209–224.

5Kremenek T.Finding Software Bugs with the Clang Static Analyzer.California:Apple Inc,2008.

6Xu ZX,Kremenek T,Zhang J.A memory model for static analysis of C programs.International Symposium on Leveraging Applications of Formal Methods,Verification and Validation.Heraklion,Crete,Greece.2010.535–548.

7Khedker U,Sanyal A,Sathe B.Data Flow Analysis:Theory and Oractice.Boca Raton,FL:CRC Press,2009.

8Xu ZB,Zhang J,Xu ZX.Melton:A practical and precise memory leak detection tool for C programs.Frontiers of Computer Science,2015,9(1):34–54.[doi:10.1007/s11704-014-3460-8]

9Reps T,Horwitz S,Sagiv M.Precise interprocedural dataflow analysis via graph reachability.Proc.of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages.San Francisco,California,USA.1995.49–61.

10Liu T,Huuck R.Case study:Static security analysis of the android goldfish kernel.International Symposium on Formal Methods.Oslo,Norway.2015.589–592.

11Muntean P,Rahman M,Ibing A,et al.SMT-constrained symbolic execution engine for integer overflow detection in C code.Proc.of 2015 Information Security for South Africa(ISSA).Johannesburg,Azania.2015.1–8.

12Wang TL,Wei T,Lin ZQ,et al.IntScope:Automatically detecting integer overflow vulnerability in X86 binary using symbolic execution.Proc.of the Network and Distributed System Security Symposium.San Diego,California,USA.2009.

13Cadar C,Godefroid P,Khurshid S,et al.Symbolic execution for software testing in practice:Preliminary assessment.Proc.of the 33rd International Conference on Software Engineering.Honolulu,HI,USA.2011.1066–1071.

14Sui YL,Yu D,Xue JL.Static memory leak detection using full-sparse value-flow analysis.Proc.of the 2012 International Symposium on Software Testing and Analysis.Minneapolis,MN,USA.2012.254–264.

15Li L,Cifuentes C,Keynes N.Practical and effective symbolic analysis for buffer overflow detection.Proc.of the 18th ACM SIGSOFT International Symposium on Foundations of Software Engineering.Santa Fe,New Mexico,USA.2010.317–326.

16Sui YL,Xue JL.SVF:Interprocedural static value-flow analysis in LLVM.Proc.of the 25th International Conference on Compiler Construction.Barcelona,Spain.2016.265–266.

17Enck W,Gilbert P,Han S,et al.TaintDroid:An informationflow tracking system for realtime privacy monitoring on smartphones.ACM Trans.on Computer Systems (TOCS),2014,32(2):5.

18Arzt S,Rastofher S,Fritz C,et al.Flowdroid:Precise context,flow,field,object-sensitive and lifecycle-aware taint analysis for android apps.ACM SIGPLAN Notices,2014,49(6):259–269.[doi:10.1145/2666356]

19Horváth G,Pataki N.Clang matchers for verified usage of the C++ standard template library.Annales Mathematicae et Informaticae,2015,44:99–109.

20Android的全系統符號執行工具-Android_S2E.http://www.infoq.com/cn/presentations/whole-system-symbol-Implementation-tools-android-s2e.[2017-01-05].

21Lattner C,Adve V.LLVM:A compilation framework for lifelong program analysis & transformation.Proc.International Symposium on Code Generation and Optimization.San Jose,CA,USA.2004.75–86.

22Spreitzenbarth M,Schreck T,Echtler F,et al.Mobilesandbox:Combining static and dynamic analysis with machine-learning techniques.International Journal of Information Security,2015,14(2):141–153.[doi:10.1007/s10207-014-0250-0]

23Zhang JX,Li ZJ,Zheng XC.PathWalker:A dynamic symbolic execution tool based on LLVM byte code instrumentation.International Symposium on Dependable Software Engineering:Theories,Tools,and Applications.Nanjing,China.2015.227–242.

24Software Assurance Reference Dataset.https://samate.nist.gov/SRD/testsuite.php.[2016-11-10].

Android Source Code Static Analysis Technology Based on Clang Compiler Front-Ends

CAO Yuan-Ye1,2,DING Li-Ping1

1(Lab of Fundamental Software,Institute of Software,Chinese Academy of Sciences,Beijing 100190,China)2(University of Chinese Academy of Sciences,Beijing 100049,China)

Android phones have a large market share in the world,and the third-party system based on Android-derived is also very popular.As the security issues appear in Android systems frequently,this paper uses Clang to compile Android source code for static analysis.This analysis extracts rules and models from published CVE vulnerabilities,and uses the improved Clang to statically analyze Android source code to detect potentially unsafe code snippets.During the analysis of the Android source code,the Clang static analyzer taints attack surface,and calls the new added STP constrained solver.Then it taints sensitive data through the symbolic execution,and makes taint analysis on the sensitive functions,sensitive operations,sensitive rules,finally reports unsafe code snippets if there are potential security risks.Through experimental analysis,this method can accurately identify unsafe source code snippets that exist in the Android source code with the same type of security risk,and this method can detect five high-risk CVE vulnerabilities in the libstagefright module.

Clang compiler; Android; static analysis; taint analysis; symbolic execution

曹原野,丁麗萍.基于Clang編譯前端的Android源代碼靜態分析技術.計算機系統應用,2017,26(10):1–10.http://www.c-s-a.org.cn/1003-3254/6013.html

國家高技術研究發展計劃(“863”計劃)(2015AA016003)

2017-01-16; 采用時間:2017-02-23

猜你喜歡
分析檢測
“不等式”檢測題
“一元一次不等式”檢測題
“一元一次不等式組”檢測題
隱蔽失效適航要求符合性驗證分析
“幾何圖形”檢測題
“角”檢測題
電力系統不平衡分析
電子制作(2018年18期)2018-11-14 01:48:24
電力系統及其自動化發展趨勢分析
小波變換在PCB缺陷檢測中的應用
中西醫結合治療抑郁癥100例分析
主站蜘蛛池模板: 国产黄网站在线观看| 国产日韩精品一区在线不卡| 高清色本在线www| 亚洲精品大秀视频| 欧美在线导航| 98精品全国免费观看视频| 亚洲综合狠狠| 国产欧美另类| 91麻豆精品视频| 免费jizz在线播放| 51国产偷自视频区视频手机观看| 亚洲人成影院午夜网站| 最新日韩AV网址在线观看| 强乱中文字幕在线播放不卡| 欧美区一区| 色综合天天娱乐综合网| 国产成人免费观看在线视频| 欧美A级V片在线观看| 国产手机在线观看| 国产成人无码AV在线播放动漫| 色综合婷婷| 一本色道久久88| 中文字幕亚洲专区第19页| 手机在线免费不卡一区二| 免费无码在线观看| 欧美69视频在线| 国产97视频在线| 亚洲色图综合在线| 91久久国产成人免费观看| 毛片最新网址| 黄色网在线免费观看| 99免费视频观看| 国产福利影院在线观看| 四虎永久在线视频| 国产午夜看片| 在线看国产精品| 午夜综合网| 麻豆国产精品一二三在线观看| 亚洲六月丁香六月婷婷蜜芽| 亚洲床戏一区| 亚洲精品无码久久毛片波多野吉| 97se亚洲综合在线| 不卡色老大久久综合网| 成年看免费观看视频拍拍| 欧美日韩国产综合视频在线观看| 免费无码在线观看| 91精品久久久久久无码人妻| 日韩成人免费网站| 9啪在线视频| 人妻一区二区三区无码精品一区 | 五月综合色婷婷| 2024av在线无码中文最新| 久久人搡人人玩人妻精品| 99国产精品一区二区| 国产va欧美va在线观看| 日韩大片免费观看视频播放| 99视频在线看| 国产视频自拍一区| 99精品在线看| 爱色欧美亚洲综合图区| 国产99在线观看| 亚洲色中色| 国产伦片中文免费观看| 久久窝窝国产精品午夜看片| 99色亚洲国产精品11p| 丁香五月激情图片| 日本在线国产| 综合色区亚洲熟妇在线| 国产精品嫩草影院视频| 一级毛片免费播放视频| 波多野结衣一区二区三区88| 欧美日本在线| 日韩一区二区三免费高清| 国产亚洲高清在线精品99| 26uuu国产精品视频| swag国产精品| 爆乳熟妇一区二区三区| 日韩欧美视频第一区在线观看| 久久亚洲精少妇毛片午夜无码 | 色婷婷亚洲综合五月| 久久婷婷五月综合色一区二区| 国产精品欧美日本韩免费一区二区三区不卡|