• 沒有找到結果。

程式碼 2 擬真執行範例

圖表 2 擬真執行流程圖

1.1.4 單一路徑擬真執行(Single Path Concolic Execution)

不同於符號執行與擬真執行,單一路徑擬真執行的目的不是在於覆蓋率的 檢測而針對於蒐集目的路徑途中經過的控制流程(control-flow)資訊。以程式碼 2 為例,單一路徑擬真程式一開始時 x=2,y=-1,當執行到第一個分支點後,路徑 限制式為 x>=0,接著遇到第二個分支點,x 與 y 滿足 x+y >0,因此路徑限制式 變為 x>=0^(x+y)<0 程式執行到 state2 後單一擬真執行結束測試不再搜索其他程

6

式執行路徑。圖表三為單一路徑擬真執行的流程。

圖表 3 單一路徑擬真執行流程圖

1.1.5 符號環境

符號環境最早是由 KLEE[5]所提出,目的是在做符號執行(symbolic execution)測試時,盡可能的視所有電腦上的資料流為符號輸入(symbolic input)

來達到測試沒有原始碼的執行檔。常見的符號環境有五種:

Symbolic file:將檔案視為為符號輸入,也就是受測程式可以透過讀取檔案的方 式來執行符號測試。

Symbolic socket:將所有的網路資料流視為符號輸入 Symbolic standard input:將標準輸入視為符號輸入 Symbolic environment variable:將系統環境變數視為符號輸入 Symbolic argument variable:將執行程式參數視為符號輸入

7

1.1.6 自 動 脅 迫 產 生 ( A u t o m a t i c E x p l o i t G e n e r a t i o n )

CRAX[13]裡面提到自動脅迫產生分成三個階段,第一:取得一個受測程式的 crash 檔案,第二:透過符號環境(symbolic environment)來執行單一路徑擬真執 行(single path concolic execution),第三:建立脅迫限制式(exploit constraint)並透 過 solver 產生脅迫(exploit)。圖 4 為完整流程。

圖表 4 Automatic Exploit Generation 流程圖

在第一步驟,可以利用 fuzzer 工具來產生 crash 檔案,或是藉由人為測試來產生,

而第二步驟主要是收集執行時的單一執行路徑限制式,這條路徑可以保證觸發受 測程式發生異常。第三步驟,脅迫限制式包刮在第二部分裡收集到的路徑限制式,

以及 shellcode 1 和 shellcode 所在的位置,還有 NOP sled。最後 solver 再根據這 些限制式來產生脅迫。

1.1.7 Crash 類型

當程式執行的過程中,如果不合法的記憶體位置被讀、或存取、執行,就會發 生異常,而針對執行異常本篇論文將其分為兩類:

1 一般泛指一段可以開啟 command shell 的程式碼

8

類別一:EIP2暫存器的值直接對應到資料流的某一區塊,例如堆疊緩衝區溢位,

通常只是將資料流的一個區段直經過記憶體後被存到 EIP 暫存器。

類別二:EIP 暫存器的直間接對應到資料流的某一區塊例如整數溢位 Integer overflow,heap overflow,uninitialized variables

1.2 研究動機與目標

1.2.1 符號環境建立很困難

KLEE 的符號環境建置使用 2500 行程式碼來修改 40 個函式呼叫(function call),而 AEG [6] 則花了 5000 程式碼來修改 70 個函式呼叫(function call),

MAYHEM [7] 則重新改寫 42 個函式呼叫總共寫了了上萬行的程式, Hellen[8]為 了達到執行檔的污染分析(taint analysis)用了 7000 行程式碼來攔截以及改寫系統 呼叫(system call)。上面提到的做法都運用修改(函式呼叫)function call 或是攔截 系統呼叫(system call) 的方法來達到符號環境建置,但是這兩種方法不只費時也

9

exploit gen control group

10

假設一個自動脅迫產生的情境,crash input 的大小為 5000byte ,那麼 CRAX 將會花費難以接受的時間在執行單一路徑 擬真執行,以及脅迫產生上,但是事 實上一個脅迫的大小,在真實環境的限制下,通常都很小,事實上,產生一個 exploit 首要關心的是,input 如何影響 EIP,因此若是能夠很快速的發現 input 中,直接影響 EIP 的位元組(critical byte),則就可以根據 critical byte 來 決 定 符 號 輸 入 的 常 常 度 以 及 位 置 , 來 達 到 增 加 C R A X 在 執 行 上 的 效 率 。 本篇論文將提出一個方法能夠快速地找尋 critical byte ,並且提出一個策略利 用 critical byte 來決定符號輸入的位置與長度。

11

第二章 相關研究

本節分四部分,第一部分列出一些運用擬真或是符號執行來做漏洞偵測,或是路 徑覆蓋率偵測的工具,第二部分介紹的工具主要是用在判斷一個可以造成軟體崩 壞(crash)檔案是否是可脅迫的(exploitable),第三部分介紹現有的自動脅迫產生 (automatic exploit generation)工具。第四部份以一個表格來呈現現有工具對符號環 境支援度做相關的比較。

2.1 符號執行

Catchconv [9]可以偵測軟體中是否有整數溢位的問題,並且嘗試產生一個可 觸發此漏洞的檔案。主要的方法是先用擬真執行來到達一個特定的目的(可能發 生整數溢位的地方)在透過執行過程中所收集的路徑限制式(path constraint )去計 算出一個可以觸發整數溢位的輸入。

是一個基於LLVM[12]的軟體測試平台,主要運用符號值執行來進行程 式路徑覆蓋(path coverage)測試以及測資產生(test case generation)。另外KLEE也 是最早提出符號環境建置的工具.

S2E [10] 是一個分析軟體行為的平台,並建置在 QEMU[13]以及 KLEE 上支

12

援(whole-system)全系統的符號執行和擬真執行而且提供完善的符號環境。

2.2 可脅迫性偵測(Exploitable Detect)

Bitblaze[11]是一個執行檔分析的平台,並且支援許多常見的軟體分析技術,

例如fuzzing,動態汙點分析(dynamic taint analysis),符號執行,以及靜態分析。

Bitblaze 也 被 應 用 在 crash 檔 案 的 檢 測 , 它 可 以 判 斷 crash 檔 案 是 否 可 脅 迫 (exploitable),並且找出系統發生crash 的真正原因。

!Exploitable[12] 是一個微軟除錯器(debugger)的套件,可以動態的檢測軟體 漏 洞 是可 被攻 擊, 並 將 受測程 式 分級為”exploitable”, “probably exploitable”,

“probably not exploitable”, 或 “unknown”。

2.3 脅迫產生(Exploit Generation)

Heelan 是第一個自動產生脅迫的工具,主要的方法是藉由汙染分析來偵測 被汙染的EIP暫存器,並透過執行過程所收集的控制流程(control-flow)資訊來產 生脅迫。另外Heelan可以直接對執行檔進行檢測,但是他必須攔截系統呼叫 (system call)才能做到汙染分析。

AEG (automatic exploit generation) 是第一個點對點(end-to-end)自動產生脅 迫的以及漏洞探測的工具,主要結合靜態分析、擬真、符號執行技術,雖然AEG 有提供符號環境,但是仍然需要受測程式的原始碼才能夠產生脅迫。

MAYHEM是第一個點對點(end-to-end)且不需要受測程式原始碼就可以自動 產生脅迫的工具,並且運用混和擬真以及符號執行的技術來增加自身效率。除此 之外MAYHEM支援五項符號環境,以及Linux 和Windows的軟體檢測。

CRAX[13] 是交通大學軟體品質實驗室發展的工具,對於一個可脅迫的crash 檔案,可以自動產生出受測程式的脅迫,而不需要受測程式的程式碼,並且同時

13

支援Linux 以及Windows平台的測試。CRAX能夠完全支援常見的符號環境,以 及在大程式的測試也有不錯的成績。

2.4 綜合比較

System Exploit-gen end -to-end

Source/binary Symbolic environment

catchconv NO Binary Yes

KLEE NO Source Incomplete

S

2

E NO Binary Yes

Bitblaze NO Binary No

!Exploitable NO Binary NO

Heelan Yes Yes Binary Incomplete

AEG Yes Yes Source Incomplete

MAYHEM Yes Yes Binary Incomplete

CRAX Yes Yes Binary Yes

表格 2 綜合比較

14 5. make_symbolic(&ch, 1);

6. if(ch==’a’)

7. printf(“ch = a”);

8. else

9. printf(“ch !=a”);

相關文件