摘 要:介紹了當前主流的靜態代碼分析技術,在分析討論其優缺點的基礎上提出了一種新的靜態代碼檢測模型。該模型結合了當前成熟的靜態分析技術,并借鑒了編譯器中數據流和控制流分析的思想,獲取上下文關聯的數據信息,從而更加準確地分析代碼中存在的安全問題。
關鍵詞:數據流分析;控制流分析;別名分析;靜態代碼分析;源代碼
中圖分類號:TP311 文獻標志碼:A
文章編號:1001-3695(2008)09-2703-03
New static analysis model in source code
LIANG Jie,ZHANG Miao,XU Guoai,YANG Yixian
(Information Security Center, State Key Laboratory of Networking Switching Technology, Beijing University of Posts Telecommunications, Beijing 100876, China)
Abstract:This paper introduced some current static analysis methods in source code, after comparing their advantage and disadvantage,gave a new model of static analysis.Based on current analysis methods, the new model gets data information in context by data flow analysis and control flow analysis which are often referred in compiler, and therefore security problems can be found more exactly.
Key words:data flow analysis; control flow analysis; alias analysis; static analysis; soure code
隨著社會信息化的不斷深入,人們不得不開始面對日益突出的信息安全問題。研究表明,相當數量的安全問題都是由于軟件自身存著的安全漏洞引起的。軟件漏洞的產生,一方面可能是設計人員在架構階段沒有明確用戶對安全性方面的需求,在設計上沒有考慮安全性,開發人員使用有風險的庫函數或引用沒有經過安全性測試的公共代碼;另一方面,開發人員可能為了測試方便在程序中開后門,或別有用心地植入惡意代碼。攻擊者利用這些漏洞繞過安全策略,以達到竊取信息的目的。
檢測軟件安全漏洞,通常從兩個方面進行,即動態分析和靜態分析。在動態分析中,需要根據實際狀況,設計多組極限測試數據,并實際地執行被測程序;靜態分析則是掃描源程序,從中找出可能導致錯誤的結構異常、控制流異常及數據流異常。靜態分析較動態而言,成本低,容易實現,能覆蓋所有路徑,且不依賴于特定的運行環境。
國內外在軟件的安全性分析領域進行了大量的研究,提出了一些可行的靜態安全性分析方法,并且構造了相應的軟件安全性分析工具。
目前靜態安全性分析方法可分為[1~7]模型檢驗、詞法分析、語義分析等。
這些檢測算法各有側重,并在現有的檢測工具中加以運用,具有一定效果,但其實現的功能,局限性還是比較大的。例如,ITS4會將所有使用的strcpy語句報告,認為不安全。這將直接導致誤報率過高, 影響代碼審查的效率和積極性;基于模式的安全漏洞并不多,這將直接導致MOPS所能維護的規則庫有限,并且只能檢查某些特定類型的漏洞;BOON雖然引入了上下文的信息,但是由于沒有精確處理控制分支的信息,僅根據數據流走向取并集,仍然存在一定程度的誤報,且該方法針對緩沖區溢出和整數溢出,具有一定的局限性。
1 分析模型
在這里,筆者考慮將各個現有的成熟的靜態代碼分析技術結合,設計一個基于上下文信息關聯的檢測模型。
1.1 引入
先來模擬一下人工分析的過程,為提煉模型作準備。
下面以一個使用文件資源的代碼段為示例:
void fun()
{
1:File f = fopen(\"c:\\\est.txt\", a+);
2:Fclose(f);
}
以下是人工審查的過程:
a)若是需要檢查文件資源泄露,需要定位到文件句柄的打開部分,鎖定風險API fopen。
b)記錄下該API返回的文件句柄,變量f。以便跟蹤該句柄的使用情況。
c)發現在行號2,f作為參數,被API fclose引用,而fclose恰好是與fopen對應的API 操作,表示文件句柄的關閉。
在此,對于這個文件資源的檢測完畢。結論:沒有資源泄露。
根據以上分析,只需要定位關鍵API,并跟蹤相應的變量使用即可。進一步,考慮下面這段帶有條件分支的代碼段:
Void fun()
{
1:File f = fopen(\"c:\\\est.txt\",a+);
2:if (fRet)
{
3:return;
}
4:fclose(f);
}
若是根據之前的原則分析,依然得出沒有錯誤的結論,然而可以看到,在行號3處,有一個return語句,這將直接導致函數退出。在這個退出分支中,打開的文件句柄沒有得到關閉,必然造成資源泄露。
反思一下分析過程,顯然忽略了這么一個事實:fopen的操作是順次必然執行的,但其對應的fclose操作則是受到if(fRet)語句控制,在其后的1控制分支中執行。對于open操作,并不是所有的退出分支都有close操作,所以導致了文件資源的泄露。
將對控制條件的處理引入分析:
a)定位關鍵API fopen。
b)跟蹤返回的句柄,變量f。
c)定位關鍵API fclose對變量f的引用。
d)比較 fopen 與 fclose是否處在同一邏輯分支。
顯然,擴充以后的分析過程,能很好地應對帶邏輯分支的代碼段。盡管實際工程中的代碼遠遠要復雜得多,但大多情況不過是各種順次控制邏輯的組合。正確地應用這種上下文分析技術,應該能夠相對快速地分析代碼中的漏洞,并確保一個較低的誤報率。
1.2 模型化
在傳統靜態分析中,風險庫是引起各種安全漏洞的API的集合,而詞法匹配通過對源代碼進行掃描,可以對風險API定位,這些恰好是上下文分析的第一步。在上下文分析的第二、三步中,需要跟蹤變量的使用情況,即對變量的初始定義以及其后的再定義、表達式引用、函數調用情況、作鏈表記錄。而在第四步中,要得到程序的分支走向,需要了解的是語句之間的控制依賴關系,恰恰這些工作與編譯器的數據流分析以及控制流分析部分相關,故這里引入一些編譯原理的概念和技術,提取上下文信息。
構造模型如圖1所示。
1.3 關鍵技術(略)
1.4 到達定值分析
編譯原理中,到達定值是這樣一個概念:定值是對x的賦值或讀值到x的語句。稱a定值d到達程序點P,若存在路徑從緊跟d的點到達P,且在這條路徑上d沒有被注銷。如果沿著這條路徑的某兩點間是讀值到a或對a的賦值,那么注銷變量a的那個定值。定義這樣一個結構:
Struct _VARNODE
{
int iLineNO;
int iValue;
bool fSet;
}
在每一個變量出現的地方,生成這么一個節點。其中iLineNO記錄行號信息,若當前語句對于該變量是賦值操作,則將fSet設置為true,并將新值記錄到iValue中;否則,fSet設置為1,iValue無效。將所有該變量的節點添加到一個鏈表,就可以得到該變量在整個工程的使用情況。這樣,就可以通過鏈表查找某行API調用時,該變量值域是否在限制之內。
1.4.1 別名分析
對同一個存儲地址存在多條訪問路徑,就會出現別名問題。訪問路徑是通過變量及一些運算符生成的表達式。例如*p、i、a、s→next,這些表達式都是訪問路徑。只有進行確切指針別名分析,才能對變量的賦值操作作準確的定位。
對于語句*p=i,訪問路徑*p與i別名,這個別名關系可以用一個二元組〈*p,i〉來表示。定義結構如下:
Struct _ARIASNODE
{
String varorg;
String varpointer;
}
對于指針或者引用的定義語句,在一張別名表中記錄該節點,varorg記錄被指向變量名,varpointer記錄指針/引用變量名。在其后的指針變量操作中,通過查表,記錄到真正指向的變量鏈表中。
1.4.2 控制依賴
在編譯原理中,控制依賴的概念用于模擬條件分支語句對程序行為的影響,它是程序控制結構的屬性,可以根據控制流圖來嚴格地定義。直觀地講,一個語句w控制依賴于語句u,如果u是一個影響、執行的條件。例如在一個ifthenelse結構中,位于條件語句兩側的語句控制依賴于該謂詞。
控制依賴圖是建立在圖論基礎上,算法標準,過程復雜。在這里拋開其實現細節,僅就結果的應用作討論。
對于程序段:
Void fun()
{
1:File f=fopen(\"c:\\\est.txt\", a+);
2:a:if (fRet)
3:{
4:b:return;
5:}
6:c:fclose(f);
7:d:return;
8:}
控制流圖如圖2所示。控制依賴圖如圖3所示。根據圖3,可以建立如表1所示的控制依賴表。
2 需要進一步完善的工作
此上下文分析模型是在傳統代碼檢測理論上應用編譯原理中較為成熟的數據流分析和控制流分析技術,但由于應用環境和目的的復雜程度不同,其得出信息的準確性仍有待改進。
1) 賦值判斷 模型只對傳統的賦值操作進行了處理,例如:a=1;a++; *a= 8等。但對于以指針/別名的形式,作為函數參數傳入函數內部再進行的數據操作,模型不能識別,只是簡單地判斷為引用。
2) 新值計算 數據流分析很大一部分工作是在各個賦值點計算變量的新值。對于傳統的表達式a=(b*6)+10,模型可以很好地處理,但是涉及到函數調用,若是工程自定義的,需要查詢自定義的函數表,切換到該函數的入口語句,進行函數調用計算。其間涉及大量的參數傳遞轉換操作,必然導致結果的不精確性。若是系統函數調用,如ch=strstr(strText, “org”),則需要正確地識別該API的返回信息。模型中只針對幾個常用的字符串操作如strstr/strcat/strcpy等進行了處理。但在實際的工程中,所調用的庫多而復雜,需要去維護/查詢/擴充一份系統庫API列表。
3) 控制條件理解 控制流分析的處理是基于語義謂詞(if/then/else、break、return等),只細化到語句/行號,對于控制條件語義上的理解完全沒有涉及。例如:
a:if (sizeof(des)>strlen(org))
b:strcpy(des,org);
在此處,對于風險API strcpy的調用是安全的,因為if語句已經對字符串長度作了判斷。然而從控制流分析僅僅得到:語句b受控于語句a,該信息完全不涉及條件語義。目前,模型對于這種情況,作了簡化處理:若控制條件中涉及到風險API中調用的變量,則認為代碼進行了安全判斷,該調用安全。顯然,這種處理是極為粗糙的,模型需要更加準確合理地去理解控制條件的語義。
參考文獻:
[1]CHESS B,McGRAW G.Static analysis for security[J].Security Privacy Magazine,2004,2(6):7679.
[2]BERGER M,HONDA K,YOSHIDA N.A logical analysis of aliasing for higherorder imperative functions[C]//Proc of ICFP’05.2005.
[3]AMTOFT T,BANERJEE A.Information flow analysis in logical form,Technical Report CIS TR 20043[R].[S.l.]:Kansas State University,2004.
[4]SABELFELD A,MYERS A C.Languagebased informationflow security[J].IEEE J Selected Areas in Communications,2003,21:519.
[5]YONG S H,HORWITZ S.Pointerrange analysis[C]//Proc ofthe 11th International Static Analysis Symposium.Verona, Italy:[s.n.],2004:26-28.
[6]SUN Qi,BANERJEE A,NAUMANN D A.Modular and constraintbased information flow inference for an objectoriented language[C]//Proc of the 11th International Static Analysis Symposium.Verona, Italy:[s.n.],2004:84-99.
[7]FLANAGAN C,FREUND S N.Type inference against races[C]//Proc of the 11th International Static Analysis Symposium.Verona, Italy:[s.n.],2004:116132.
[8]McGRAW G.Software security:building security[M].[S.l.]:Addison Wesley Professional,2006.
[9]WAGNER D,FOSTER J S,BREWER E A,et al.A first step towards automated detection of buffer overrun vulnerabilities[C]//Proc ofNetworking and Distributed System Security Symposium.San Diego, California:[s.n.],2000.
[10]VIEGA J,BLOCH J T,KOHNO T,et al.ITS4:a static vulnerability scanner for C and CII code[C]//Proc ofthe 16th Annual Computer Security Applications Conference.2000.
[11]CHEN Hao,WAGNER D.MOPS:an infrastructure for examining security properties of software[C]//Proc of the 9th ACM Conf Computer and Communications Security.New York:ACM,2002:235-244.