張洪澤,洪 征,周勝利,馮文博
1.中國人民解放軍陸軍工程大學(xué) 指揮控制工程學(xué)院,南京210000
2.浙江警察學(xué)院 計算機與信息技術(shù)系,杭州310000
協(xié)議漏洞挖掘是保證網(wǎng)絡(luò)通信安全的重要手段。模糊測試是目前最常用的協(xié)議漏洞挖掘方法,它通過向協(xié)議實體輸入變異的報文,監(jiān)控協(xié)議實體的運行狀況,分析協(xié)議實體發(fā)生的異常,從而發(fā)現(xiàn)潛在的安全漏洞。模糊測試具有自動化程度高、發(fā)現(xiàn)的漏洞實際可用等優(yōu)點[1]。
根據(jù)輸入報文相互之間是否存在關(guān)聯(lián)關(guān)系,網(wǎng)絡(luò)通信協(xié)議可分為無狀態(tài)協(xié)議(Stateless Protocol)和有狀態(tài)協(xié)議(Stateful Protocol)兩類[2]。無狀態(tài)協(xié)議是指報文發(fā)送方輸出的各個報文之間沒有關(guān)聯(lián)性,例如ICMP協(xié)議的每個請求報文各自獨立,相互之間沒有關(guān)聯(lián)關(guān)系。而對于有狀態(tài)協(xié)議,協(xié)議實體會記錄所接收到的報文信息,在處理報文后可能會出現(xiàn)協(xié)議狀態(tài)的變化,例如FTP協(xié)議與SMTP協(xié)議都屬于有狀態(tài)協(xié)議。相比于無狀態(tài)協(xié)議模糊測試,對有狀態(tài)協(xié)議進(jìn)行模糊測試更復(fù)雜。因為當(dāng)測試用例與協(xié)議實體狀態(tài)不匹配時,測試用例會被直接丟棄,為了保證測試用例盡可能被協(xié)議實體接受,測試時需要依賴協(xié)議的狀態(tài)模型,根據(jù)協(xié)議實體所處的協(xié)議狀態(tài)輸入測試用例[3]。
網(wǎng)絡(luò)通信協(xié)議的模糊測試最早可追溯到1999年芬蘭Oulu大學(xué)研發(fā)的網(wǎng)絡(luò)協(xié)議安全測試軟件PROTOS[4]。PROTOS發(fā)現(xiàn)了不少的協(xié)議實體程序的安全漏洞,但是它不是通用的測試框架,軟件靈活性較差,應(yīng)用范圍狹窄。2002年,Aitel開發(fā)了一款通用協(xié)議測試框架工具SPIKE[5]。SPIKE是一款可以定制的模糊測試器框架,能夠方便地實現(xiàn)代碼重用,但是不能靈活描述報文中字段之間的約束關(guān)系,并且SPIKE只適用于無狀態(tài)網(wǎng)絡(luò)協(xié)議的測試,應(yīng)用范圍受限。2013年,IOACTIVE發(fā)布了著名模糊測試框架Peach 3.0[6]。Peach 3.0是一個靈活的模糊測試框架,使用XML文件作為測試腳本來定義測試對象以及測試方法,充分利用了XML文件低耦合、易分離的優(yōu)點,促進(jìn)了模糊測試代碼的重用。除了上述測試工具,研究者也提出不少模糊測試的優(yōu)化方法。例如Kitagawa等人提出狀態(tài)級(State-Level)變異的模糊測試方法AspFuzz[7]。AspFuzz可以自動構(gòu)造與正常報文交互順序相違背的測試序列,發(fā)現(xiàn)報文異常輸入順序引起的協(xié)議缺陷,但是其測試方法存在組合爆炸的問題。Zhao等人提出基于回歸協(xié)議狀態(tài)機的模糊測試方法RFSM-Fuzzing[8]。該方法通過狀態(tài)引導(dǎo)對每個協(xié)議狀態(tài)進(jìn)行測試,對協(xié)議漏洞挖掘有較好的效果,但是測試過程存在冗余交互較多、測試效率低下的問題。Pan等人提出一種基于文法驅(qū)動的協(xié)議測試方法[9]。該方法利用高階屬性文法建立數(shù)據(jù)模型,通過遍歷語義樹指導(dǎo)測試用例生成,有效避免了協(xié)議字段的漏測或者重復(fù)測試。Ma等人提出基于規(guī)則的狀態(tài)機(Rule-Based State Machine)與狀態(tài)規(guī)則樹(Stateful Rule Tree)來指導(dǎo)模糊測試序列生成的方法[10]。作者認(rèn)為如果某個狀態(tài)遷移對應(yīng)的輸入不會引發(fā)協(xié)議實體異常,那么則認(rèn)為該遷移是安全遷移,在測試期間可以將其移除從而縮小測試空間,但是這種方法可能出現(xiàn)測試不完全的問題??傮w上看,現(xiàn)有的模糊測試技術(shù)沒有充分利用協(xié)議狀態(tài)轉(zhuǎn)換關(guān)系開展測試,也沒有對輸入報文和響應(yīng)報文進(jìn)行必要的相關(guān)性分析,在測試實施過程中較為盲目,測試效率低下,測試的覆蓋率偏低。
本文旨在提高測試效率與測試覆蓋率,提出一種針對有狀態(tài)協(xié)議的模糊測試優(yōu)化方法。
有狀態(tài)網(wǎng)絡(luò)通信協(xié)議通常采用確定有限狀態(tài)機(Deterministic Finite Automaton,DFA)作為協(xié)議交互的形式化描述模型。確定有限狀態(tài)機的定義如下所示[11]。
定義1(確定有限狀態(tài)機)定義為一個六元組M=(S,I,O,δ,β,T),其中:
S={s0,s1,…,sn}是有限狀態(tài)集合,s0∈S表示M的初始狀態(tài),且在任意時刻,M只能處于某一狀態(tài)si,有限狀態(tài)機由s0狀態(tài)開始接收輸入;
I={i1,i2,…,im}是有限輸入符號集合;
O={o1,o2,…,om}是有限輸出符號集合;
δ:S×I→S是狀態(tài)遷移函數(shù),它是一對一的映射;
β:S×I→O是狀態(tài)輸出函數(shù);
T是終結(jié)狀態(tài)集合。
當(dāng)DFA應(yīng)用于網(wǎng)絡(luò)協(xié)議描述時,I={i1,i2,…,im}表示協(xié)議實體可接受并正常處理的輸入報文集合,O={o1,o2,…,om}表示協(xié)議實體輸出的報文集合,以M表示協(xié)議狀態(tài)機。以FTP協(xié)議[12]狀態(tài)機為例,其輸入輸出報文類型的抽象符號如表1所示,M包括7個狀態(tài),狀態(tài)集合S={s1,s2,s3,s4,s5,s6,s7}。狀態(tài)機M如圖1所示,其中s0到s1的遷移表示為i1/o1,它表示協(xié)議實體處于s0狀態(tài)時,如果接受USER類型報文(用i1表示),將輸出331類型報文(用o1表示),同時協(xié)議實體狀態(tài)遷移至s1狀態(tài)。
表1 FTP協(xié)議輸入輸出報文類型的抽象符號列表
圖1 FTP協(xié)議狀態(tài)機
對于有狀態(tài)協(xié)議模糊測試,為了提高測試覆蓋率,通常需要使協(xié)議實體處于某一指定狀態(tài),然后輸入與狀態(tài)相對應(yīng)的測試用例進(jìn)行測試。測試時需要依賴網(wǎng)絡(luò)協(xié)議交互規(guī)則,根據(jù)協(xié)議狀態(tài)機構(gòu)造測試序列。傳統(tǒng)的有狀態(tài)協(xié)議模糊測試過程[8,13-14]主要包括三個步驟:首先,通過正常的報文交互,將協(xié)議實體引導(dǎo)至某個待測協(xié)議狀態(tài),這些正常交互報文所構(gòu)成的序列稱為前置引導(dǎo)序列。然后,向協(xié)議實體輸入與被測狀態(tài)相對應(yīng)的變異報文,所涉及的變異報文被稱為測試用例。如果檢測到協(xié)議實體在處理測試用例后出現(xiàn)系統(tǒng)崩潰或者停止響應(yīng)等異常情況,則需保存錯誤現(xiàn)場并進(jìn)一步分析。最后,如果未檢測到異常,還需按照特定順序輸入正常報文將協(xié)議實體引導(dǎo)至終止?fàn)顟B(tài),準(zhǔn)備下一輪測試。這些正常報文所構(gòu)成的序列被稱為回歸序列。前置引導(dǎo)序列、測試用例與回歸序列共同組成測試序列。如對于圖1所示的FTP協(xié)議狀態(tài)機,生成測試序列如表2所示,其中,~i表示測試用例。
表2 測試序列示例
評價模糊測試方法的優(yōu)劣可以采用測試效率與測試覆蓋率兩個評價指標(biāo)?,F(xiàn)有的模糊測試方法進(jìn)行有狀態(tài)協(xié)議的模糊測試時,主要存在以下三方面的不足:
(1)輔助類型報文交互時間耗費高,測試效率低下。
網(wǎng)絡(luò)協(xié)議模糊測試需要將報文通過網(wǎng)絡(luò)傳輸?shù)絽f(xié)議實體程序,報文在傳輸節(jié)點的等待、處理以及在網(wǎng)絡(luò)中的傳輸都需要時間,每個發(fā)送的報文時間耗費是不可忽略的問題[15]?,F(xiàn)有的測試方法通常只側(cè)重于提高測試用例的有效性,沒有考慮測試流程的優(yōu)化,導(dǎo)致測試序列中只有少部分報文屬于測試用例,其他大部分是前置引導(dǎo)序列、回歸序列等輔助報文,這些輔助報文會產(chǎn)生額外的時間開銷,使得單位時間內(nèi)成功完成測試的測試用例數(shù)量很少,引發(fā)協(xié)議實體異常概率相應(yīng)偏小,測試效率偏低。
(2)不能保證所有的狀態(tài)遷移都進(jìn)行測試,測試覆蓋率不高。
在對有狀態(tài)協(xié)議進(jìn)行模糊測試時,需要考慮被測協(xié)議實體程序的代碼覆蓋率,程序代碼覆蓋得越充分,表明測試越完善[16]。對于程序源碼未知的協(xié)議實體進(jìn)行模糊測試,難以確定代碼覆蓋率,因此通常利用協(xié)議狀態(tài)遷移覆蓋率對測試方法進(jìn)行評估,協(xié)議狀態(tài)遷移覆蓋得越充分,表明測試越完善。然而,現(xiàn)有的方法難以保證對所有的狀態(tài)遷移都進(jìn)行測試,協(xié)議實體程序代碼測試覆蓋不夠充分,影響漏洞挖掘效果。
(3)無法保證輸入報文與協(xié)議實體狀態(tài)相對應(yīng),產(chǎn)生無效的報文交互。
協(xié)議實體程序在處理報文時,需要經(jīng)過語法解析、語義解析與程序執(zhí)行三個步驟[17]。測試用例觸發(fā)協(xié)議實體程序異常或者正常處理輸入報文必須首先通過前兩步,即測試用例或者正常報文需要滿足兩個條件:協(xié)議格式語法約束以及與協(xié)議實體狀態(tài)相對應(yīng)。而目前模糊測試采用的主要是固定模式的測試方法,即在每次測試之前預(yù)先生成測試序列,測試時不再對測試序列進(jìn)行調(diào)整。這種方法存在盲目性。因為測試用例被協(xié)議實體直接拋棄還是接收處理是不確定的,輸入測試用例后協(xié)議實體狀態(tài)是無法預(yù)知的,可能出現(xiàn)后續(xù)報文(例如回歸序列)與協(xié)議實體狀態(tài)不對應(yīng)的情形,這導(dǎo)致報文交互是無效的。
針對上述分析,本文提出一種基于協(xié)議狀態(tài)遷移遍歷的模糊測試優(yōu)化方法。首先將尋找遍歷狀態(tài)機所有遷移的路徑問題轉(zhuǎn)化為有向圖的中國郵路問題,通過求解有向圖的中國郵路問題獲取協(xié)議狀態(tài)機的最優(yōu)遍歷路徑;然后遵循最優(yōu)遍歷路徑的所有遷移依次進(jìn)行測試;測試時根據(jù)響應(yīng)報文信息推斷協(xié)議實體狀態(tài),動態(tài)選擇合適的測試用例或者正常報文,確保測試過程中發(fā)給協(xié)議實體的報文與其協(xié)議狀態(tài)相對應(yīng),避免無效的報文交互,進(jìn)而提高測試效率。此外,通過精心構(gòu)造的唯一輸入/輸出序列(Unique Input/Output Sequences,UIO)檢測協(xié)議實體異常,及時發(fā)現(xiàn)協(xié)議狀態(tài)的異常遷移。
在實施模糊測試時,協(xié)議實體對每個測試用例會給出相應(yīng)的反饋信息,例如當(dāng)測試用例不能被正確地接收處理時,協(xié)議實體會通過響應(yīng)報文的形式告知。例如,F(xiàn)TP服務(wù)器會反饋包含“500 Syntax error unknown command”信息的報文;SMTP服務(wù)器會反饋包含“503 Bad sequence of commands”信息的報文。為方便表述,當(dāng)協(xié)議實體處于狀態(tài)si,輸入報文im,將協(xié)議實體處理報文im后輸出的響應(yīng)報文on稱為由輸入im與狀態(tài)si確定的期望響應(yīng)報文。如果得到的輸出不是正常的響應(yīng)報文on,而是諸如提示輸入報文語法錯誤、錯誤命令序列、命令未實現(xiàn)、動作未完成等負(fù)面回答信息的報文,或者是非狀態(tài)si的響應(yīng)報文,統(tǒng)一稱之為由輸入im與狀態(tài)si確定的非期望響應(yīng)報文,表示為-on。需要說明的是,在測試時,若在設(shè)定時間閾值內(nèi)未返回任何報文,也視為得到的是非期望響應(yīng)報文。
網(wǎng)絡(luò)協(xié)議模糊測試過程主要是為了發(fā)現(xiàn)能夠觸發(fā)協(xié)議實體異常的測試用例。然而很多測試用例并不會觸發(fā)協(xié)議實體異常,這些測試用例主要可以分為兩類:一類是由于測試用例存在畸形數(shù)據(jù),如果測試用例無法通過語法驗證,它們會被協(xié)議實體直接拋棄,沒有進(jìn)行程序執(zhí)行,一般不會引發(fā)協(xié)議實體程序異常和狀態(tài)的跳轉(zhuǎn),此時協(xié)議實體會輸出非期望響應(yīng)報文。另一類是測試用例符合協(xié)議格式規(guī)范,能夠正常被程序執(zhí)行處理,可以引發(fā)狀態(tài)跳轉(zhuǎn)并輸出期望響應(yīng)報文。例如,針對某些FTP協(xié)議實體程序進(jìn)行模糊測試時,如果對MKD(創(chuàng)建目錄)命令的參數(shù)變異生成的某些測試用例,這些測試用例可能仍屬于正常報文,程序輸出的是期望響應(yīng)報文。正是因為這兩類測試用例的存在,使得輸入測試用例之前無法預(yù)知在輸入測試用例之后協(xié)議實體狀態(tài)的變化。
協(xié)議模糊測試為了檢測協(xié)議實體程序能否正確處理畸形數(shù)據(jù),判斷協(xié)議實體程序是否有足夠的健壯性,在模糊測試時,不僅需要利用調(diào)試器查看內(nèi)存使用情況等方法發(fā)現(xiàn)協(xié)議實體內(nèi)存訪問異常等問題,還要考慮協(xié)議狀態(tài)異常遷移問題,發(fā)掘協(xié)議實體程序的安全缺陷。
以協(xié)議實體處于si狀態(tài),輸入正常報文im后協(xié)議實體遷移至狀態(tài)sj為例。所謂的協(xié)議狀態(tài)異常遷移,在一致性測試領(lǐng)域[18],指的是當(dāng)協(xié)議實體接收到im后,協(xié)議實體狀態(tài)未遵循協(xié)議狀態(tài)機遷移至sj狀態(tài),而是其他非sj狀態(tài)。這種情形說明協(xié)議實體間的交互存在偏差,是一種潛在錯誤。在對協(xié)議進(jìn)行模糊測試時,當(dāng)發(fā)送由正常報文im變異生成的測試用例后,如果利用查看調(diào)試器等方法未發(fā)現(xiàn)異常,但是協(xié)議實體狀態(tài)既不處于si狀態(tài)也不處于sj狀態(tài),說明協(xié)議實體出現(xiàn)狀態(tài)異常遷移。這種由測試用例引發(fā)協(xié)議狀態(tài)異常遷移意味著協(xié)議實體程序不夠健壯,通信過程不可靠,是一種安全缺陷。因此,協(xié)議實體狀態(tài)異常遷移檢測非常必要。為了及時發(fā)現(xiàn)協(xié)議狀態(tài)是否異常遷移,需要在測試后準(zhǔn)確地對協(xié)議實體所處的狀態(tài)進(jìn)行判斷。
對于黑盒測試,無法通過觀察協(xié)議實體內(nèi)部動作判斷協(xié)議實體狀態(tài),可以采用向協(xié)議實體發(fā)送UIO序列[19]判斷協(xié)議實體所處的狀態(tài)。所謂UIO序列,指的是當(dāng)協(xié)議實體處于某一狀態(tài)si時,向協(xié)議實體發(fā)送一個報文序列,報文序列表示為P=(ix,iy,…,iz),ix,iy,iz∈I,協(xié)議實體輸出報文組成的序列與其他非si狀態(tài)下輸入P而得到的輸出報文組成的序列都不同,報文序列P稱為狀態(tài)si的UIO序列,記為UIO(si)。UIO序列可以唯一標(biāo)識協(xié)議狀態(tài)si。例如在圖1所示的狀態(tài)機中,當(dāng)協(xié)議實體處于s2狀態(tài)時,輸入報文序列(i3,i4)會輸出報文序列(o3,o4),而在其他任何狀態(tài)下輸入(i3,i4)構(gòu)成的序列都不會輸出報文序列(o3,o4),因此報文序列(i3,i4)為狀態(tài)s2的UIO序列。
文獻(xiàn)[8]利用UIO序列,通過觀察協(xié)議實體的輸出報文序列檢測協(xié)議實體所處的狀態(tài)。具體而言,其方法在輸入測試用例后,為了判斷協(xié)議實體是否處于si狀態(tài),向協(xié)議實體輸入si狀態(tài)所對應(yīng)的UIO序列。如果協(xié)議實體輸出的報文序列與UIO序列對應(yīng)的輸出報文序列相符,則說明協(xié)議實體處于si狀態(tài),否則說明協(xié)議實體不處于si狀態(tài)。這種方法在每次輸入測試用例之后,都需要輸入對應(yīng)的整個UIO序列,使得測試時不得不發(fā)送與接收額外的報文,影響測試效率。此外,文獻(xiàn)[8]方法也存在UIO序列與狀態(tài)不對應(yīng)而導(dǎo)致報文無效交互的問題。為解決此問題,本文提出了利用交叉迭代策略構(gòu)造UIO序列。
模糊測試優(yōu)化基本思想如下:首先需要在協(xié)議狀態(tài)機上尋找遍歷狀態(tài)機所有狀態(tài)遷移,并且盡可能短的路徑,為方便敘述,該路徑以O(shè)PT表示。測試過程從OPT對應(yīng)的第一個狀態(tài)開始實施,以協(xié)議狀態(tài)si為例,狀態(tài)si在OPT中鄰接的下一個協(xié)議狀態(tài)為sj,狀態(tài)si與狀態(tài)sj之間的遷移對應(yīng)的正常輸入報文為im。測試時向協(xié)議實體輸入由im變異生成的測試用例,檢測協(xié)議實體是否出現(xiàn)了異常,如果出現(xiàn)了異常,需要保存輸入數(shù)據(jù)待進(jìn)一步分析調(diào)試。如果沒有出現(xiàn)異常,需要推斷協(xié)議實體的狀態(tài),以決定如何實施下一步的測試。協(xié)議實體的狀態(tài)推斷主要依據(jù)協(xié)議實體的響應(yīng)報文。對于輸入的測試用例,如果協(xié)議實體的響應(yīng)報文是協(xié)議狀態(tài)si和輸入im所對應(yīng)的期望響應(yīng)報文,那么表明測試用例被協(xié)議實體正常接收處理,協(xié)議實體狀態(tài)已經(jīng)處于sj狀態(tài),可以輸入下一個狀態(tài)遷移所對應(yīng)的測試用例進(jìn)行下一步測試。如果協(xié)議實體的響應(yīng)報文屬于協(xié)議狀態(tài)si和輸入im所對應(yīng)的非期望響應(yīng)報文,那么協(xié)議實體仍可能處于si狀態(tài),也可能由于測試用例的作用,跳轉(zhuǎn)至狀態(tài)si之外的狀態(tài)。在這種情況下,繼續(xù)需要輸入正常輸入報文im,觀察協(xié)議實體的響應(yīng)。如果響應(yīng)報文是狀態(tài)si和輸入im所對應(yīng)的非期望響應(yīng)報文,那么在輸入報文im之前,協(xié)議實體可能出現(xiàn)異常,需要保存輸入數(shù)據(jù)進(jìn)一步分析。如果響應(yīng)報文是狀態(tài)si和輸入im所對應(yīng)的期望響應(yīng)報文,那么此時協(xié)議實體已經(jīng)被引導(dǎo)至sj狀態(tài),繼續(xù)輸入sj狀態(tài)與下一狀態(tài)的遷移對應(yīng)的測試用例進(jìn)行測試。為了檢測在輸入im變異生成測試用例之后協(xié)議實體狀態(tài)是否發(fā)生異常遷移,需要在輸入測試用例之后輸入狀態(tài)si對應(yīng)的UIO序列,那么在測試時輸入由im變異生成的測試用例之后,同時保證后續(xù)輸入的其他報文可以構(gòu)成狀態(tài)si對應(yīng)的UIO序列。如此依次推進(jìn),直至OPT的終止?fàn)顟B(tài)完成一輪測試。
在模糊測試優(yōu)化實施過程中主要有兩個問題:
(1)如何在協(xié)議狀態(tài)機上尋找遍歷協(xié)議狀態(tài)機所有遷移,并且盡可能短的路徑。
(2)在輸入由im變異生成的測試用例后,如何保證后續(xù)輸入的報文可以構(gòu)成狀態(tài)si對應(yīng)的UIO序列。
下文將依次進(jìn)行論述。
該節(jié)將解決3.3節(jié)提出的問題(1)。需要說明的是,之所以要在協(xié)議狀態(tài)機上尋找遍歷協(xié)議狀態(tài)機所有遷移,并且盡可能短的路徑,是因為如果依據(jù)OPT上狀態(tài)遷移的順序依次對每個狀態(tài)遷移進(jìn)行測試,可以保證所有狀態(tài)遷移都能夠被測試,盡可能短的路徑可以減小異常定位分析的工作量。
有向圖的中國郵路問題(Digraph Chinese Postman Problem,DCPP)是尋找經(jīng)歷有向圖中每條有向邊至少一次并且長度最短的遍歷路線,這種遍歷路線也被稱為最優(yōu)郵遞路線[20]??蓪f(xié)議狀態(tài)機映射為有向圖,然后再基于DCPP,尋找一條經(jīng)歷有向圖中所有有向邊并且長度最小的遍歷路線,根據(jù)獲取的有向圖遍歷路線,找到遍歷協(xié)議狀態(tài)機所有遷移的最短路徑。依據(jù)該遍歷路徑上狀態(tài)遷移的先后順序進(jìn)行測試,即可以對所有狀態(tài)遷移進(jìn)行測試,有效避免漏測問題。下面先給出有向圖的定義。
定義2(有向圖)以二元組表示一個有向圖,記為DG=(V,E),其中DG是有向圖的名稱,V={v0,v1,…,vn}是圖的頂點集合,E={e0,e1,…,em}是圖的有向邊集合。
協(xié)議狀態(tài)機M映射為有向圖DG的過程如下:將狀態(tài)集合S映射成有向圖的頂點集合V,使得任意狀態(tài)均有唯一頂點與其對應(yīng)。將狀態(tài)的遷移映射為有向邊,使得任意狀態(tài)si(對應(yīng)頂點為vi)至sj(對應(yīng)頂點為vj)的狀態(tài)遷移(輸入為ik∈I,輸出為ol∈O)均有唯一有向邊(以vi為頂點,vj為終點)與其對應(yīng),并且該有向邊以輸入ik∈I和輸出ol∈O進(jìn)行標(biāo)記,進(jìn)而得到狀態(tài)機M唯一對應(yīng)的有向圖DG。
DCPP求解算法的適用條件是有向圖為強連通圖。強連通圖是指有向圖的每個頂點都可以到達(dá)其他任意頂點,然而協(xié)議狀態(tài)機映射而成的有向圖可能不是強連通圖。例如,圖1中FTP協(xié)議狀態(tài)機映射而成的有向圖中狀態(tài)s2所對應(yīng)的頂點v2無法到達(dá)s1對應(yīng)的頂點v1,該有向圖不滿足DCPP求解條件。為解決這一問題,采用了如下策略:在模糊測試過程中,一次會話結(jié)束后需要啟動新的會話,因此將狀態(tài)機M的終結(jié)狀態(tài)返回初始狀態(tài)作為一次狀態(tài)遷移,將其稱為虛擬遷移,將虛擬遷移添加到狀態(tài)機中,添加虛擬遷移后的狀態(tài)機用V-M表示,如圖2所示。在V-M中,每個狀態(tài)可以到達(dá)其他任意狀態(tài),V-M所對應(yīng)的有向圖為強聯(lián)通圖,其對應(yīng)的DCPP可以求解。
圖2 添加虛擬遷移后的狀態(tài)機V-M
協(xié)議狀態(tài)機映射為有向圖DG后,將遍歷所有狀態(tài)遷移的最短路徑的問題轉(zhuǎn)化為DCCP問題進(jìn)行求解。DCCP問題存在多項式時間解法。DCCP的經(jīng)典求解算法是在有向圖DG上增加有向邊,使得每個頂點的入度和出度都相等,得到一個有向歐拉圖DG',歐拉圖DG'的歐拉回路就是遍歷DG中所有遷移的最短路徑。限于篇幅原因,算法細(xì)節(jié)不再贅述,詳見文獻(xiàn)[20]。在對V-M遍歷所有狀態(tài)遷移的最短路徑進(jìn)行求解的過程中,以狀態(tài)s0對應(yīng)的v0結(jié)點出發(fā),優(yōu)先遍歷每個頂點的自循環(huán)邊。根據(jù)DCCP求解得到遍歷有向圖DG中所有有向邊的最短路線,進(jìn)而尋找到遍歷協(xié)議狀態(tài)機所有狀態(tài)遷移的最短路徑,稱之為最優(yōu)遍歷路徑(Optimal Traversal Path,OTP)。在模糊測試時,以遍歷協(xié)議狀態(tài)機對應(yīng)的OTP為基礎(chǔ)進(jìn)行模糊測試,可保證對協(xié)議狀態(tài)機中的所有狀態(tài)遷移進(jìn)行測試。
圖3 最優(yōu)遍歷路徑OTP
由圖2對應(yīng)的V-M狀態(tài)機求得最優(yōu)遍歷路徑OTP,如圖3所示。沿用協(xié)議狀態(tài)機的概念,OTP中包含協(xié)議狀態(tài)與狀態(tài)遷移,其中OTP的第一個協(xié)議狀態(tài)s0稱為OTP的初始狀態(tài),最后一個協(xié)議狀態(tài)s7稱為OTP的終止?fàn)顟B(tài)。從OTP的初始狀態(tài)開始遍歷至OTP的終止?fàn)顟B(tài),期間經(jīng)歷了協(xié)議狀態(tài)機M的所有狀態(tài)遷移(包括虛擬遷移)。
該節(jié)通過設(shè)計交叉迭代策略解決3.3節(jié)問題(2)。交叉迭代策略基于這樣一種思想:由3.3節(jié)可知,當(dāng)協(xié)議實體處于狀態(tài)si,輸入相應(yīng)的測試用例之后,如果沒有發(fā)現(xiàn)協(xié)議實體異常,將遵循OPT繼續(xù)輸入正常報文與測試用例執(zhí)行測試。對于這些后續(xù)發(fā)送的報文,其中某些報文可組成報文序列P',如果報文序列P'是狀態(tài)si的UIO序列,那么可利用P'檢測狀態(tài)si是否發(fā)生異常遷移,而無需再構(gòu)造獨立的UIO序列。
接下來介紹上述策略實施過程。以O(shè)TP的初始狀態(tài)為起點,以O(shè)TP的終止?fàn)顟B(tài)作為終點,OTP上相鄰的兩個狀態(tài),以狀態(tài)si與sj為例,對狀態(tài)之間的遷移進(jìn)行如下判斷:查看OPT中狀態(tài)si與下一個si狀態(tài)或者M(jìn)的終止?fàn)顟B(tài)之間的遷移對應(yīng)的報文序列,該報文序列記作P。在實際測試過程中,在測試狀態(tài)si與sj之間遷移之后,如果未發(fā)現(xiàn)異常并繼續(xù)測試,那么后續(xù)輸入的報文序列P'是由報文序列P與測試用例構(gòu)成。如果報文序列P是狀態(tài)si對應(yīng)的UIO序列,由定理可知,報文序列si也是UIO序列,此時可以保證在測試狀態(tài)si與sj之間的遷移后,接下來會輸入相應(yīng)的UIO序列用于檢測協(xié)議實體是否發(fā)生異常遷移。為方便后續(xù)操作,此時需要對狀態(tài)si與sj之間遷移進(jìn)行標(biāo)記。如果報文序列P不是狀態(tài)si對應(yīng)的UIO序列,那么P'也不是UIO序列,狀態(tài)si與sj之間遷移測試后不會有UIO序列進(jìn)行檢測,那么不對狀態(tài)si與sj之間遷移進(jìn)行標(biāo)記。之所以查看OPT中狀態(tài)si與下一個si狀態(tài)或者M(jìn)的終止?fàn)顟B(tài)之間的遷移對應(yīng)的報文序列,是因為狀態(tài)si在被測后,在協(xié)議實體處于下一個si狀態(tài)或者會話結(jié)束前就要檢測是否出現(xiàn)異常遷移。
定理 如果P=(ix,iy,…,iz)是狀態(tài)si的UIO序列,那 么 P'=((~ix|-,ix)|~ix,(~iy|-,iy)|~iy,…,(~iz|-,iz)|~iz)也是狀態(tài)si的UIO序列,其中~ix|-表示要么輸入~ix要么無輸入,(~ix|-,ix)表示由~ix|-與ix組成的輸入序列。
證明 當(dāng)協(xié)議實體處于狀態(tài)si時,輸入狀態(tài)si的UIO序列P,由UIO定義可知,協(xié)議實體必會有唯一輸出(ox,oy,…,oz)。而同樣協(xié)議實體程序處于狀態(tài)si時,輸入P',那么協(xié)議實體必然輸出((o,oy)|oy,…,(-,oz)|oz),其中ox)|ox表示為o-與ox組成的輸出序列。又因為輸出(ox,oy,…,oz)是唯一確定的,并且非期望響應(yīng)報文不會與其他任何期望響應(yīng)報文相同,所以-,oz)|oz)也是協(xié)議實體唯一確定的輸出,則P'也是狀態(tài)si的UIO序列。
上述策略實施過程也就是判斷OPT上任意兩個相鄰的狀態(tài)之間的遷移是否可以被標(biāo)記,對整個OPT而言,詳細(xì)的標(biāo)記步驟如下:
步驟1對于OTP中的某一個狀態(tài)si,以sj表示其鄰接狀態(tài)。首先判斷si是否為原始狀態(tài)機M中的終止?fàn)顟B(tài),如果是終止?fàn)顟B(tài),那么狀態(tài)si與狀態(tài)sj之間遷移是虛擬遷移,虛擬遷移不被標(biāo)記,跳至執(zhí)行步驟3;否則繼續(xù)執(zhí)行步驟2。
步驟2從狀態(tài)si出發(fā)順序遍歷,查看OTP中狀態(tài)si與其之后的第一個si狀態(tài)或者第一個原始狀態(tài)機M終止?fàn)顟B(tài)之間的最短遷移路徑。如果這段遷移路徑對應(yīng)的輸入序列是si狀態(tài)的UIO序列,那么對狀態(tài)si至鄰接狀態(tài)sj之間的遷移進(jìn)行標(biāo)記,然后執(zhí)行步驟3;否則,該步驟不進(jìn)行任何標(biāo)記,直接執(zhí)行步驟3。
步驟3判斷狀態(tài)sj是否為OTP的終止?fàn)顟B(tài),如果狀態(tài)sj是OTP的終止?fàn)顟B(tài),那么完成OTP的標(biāo)記;否則,跳至執(zhí)行步驟1,對狀態(tài)sj與其下一個鄰接狀態(tài)進(jìn)行遞歸操作。
例如對圖4最優(yōu)遍歷路徑OTP進(jìn)行標(biāo)記,第一個s4狀態(tài)至其之后第一個s4狀態(tài)(即OTP的第二個s4狀態(tài))之間遷移需要輸入i5、i7、i11、i3與i4,依次經(jīng)過狀態(tài)s5、s6、s2與s3,并且輸出為o5、o5、o4、o3、o4,其中報文序列(i5,i7,i11,i3,i4)是狀態(tài)s4的UIO序列,因此對第一個s4至與其下一個鄰接狀態(tài)s5之間的遷移進(jìn)行標(biāo)記,然后再以同樣的方法繼續(xù)判斷狀態(tài)s5以及其下一個鄰接狀態(tài)之間遷移是否應(yīng)被標(biāo)記,直至對所有狀態(tài)都進(jìn)行判斷并標(biāo)記相應(yīng)遷移,標(biāo)記后的狀態(tài)遷移記作“|”,如圖4所示。
圖4 標(biāo)記后的最優(yōu)遍歷路徑
基于前期分析與準(zhǔn)備工作,本章將詳細(xì)闡述動態(tài)模糊測試流程。遵循最優(yōu)遍歷路徑OTP,以si和其鄰接的下一個狀態(tài)sj之間的遷移為例,對應(yīng)遷移的合法輸入報文是im,期望響應(yīng)報文是om,非期望響應(yīng)報文記作報文im對應(yīng)的測試用例的集合記作Tim={~im1,~im2,…,~imn},測試時,需要使用一個隊列Q用以保存包含輸入的報文信息。測試流程圖如圖5所示。
圖5 模糊測試流程
動態(tài)模糊測試流程主要包括以下6個步驟:
步驟1判斷狀態(tài)si至狀態(tài)sj之間遷移是否被標(biāo)記過。如果該遷移被標(biāo)記,那么滿足后續(xù)輸入報文可構(gòu)成UIO序列的條件,執(zhí)行步驟2進(jìn)行測試;否則,執(zhí)行步驟5。
步驟2輸入測試用例~imj∈Tim,同時將測試用例信息記錄在隊列Q中,監(jiān)測協(xié)議實體在處理測試用例后是否發(fā)生內(nèi)存訪問錯誤、程序崩潰等異常。如果出現(xiàn)異常,依據(jù)記錄的測試用例信息進(jìn)一步分析調(diào)試;否則,繼續(xù)執(zhí)行步驟3。
步驟3判斷協(xié)議實體在處理測試用例后的輸出是否為om。如果輸出是om,說明~imj可以被協(xié)議實體接受并正常處理,此時協(xié)議實體的狀態(tài)視為已遷移至sj狀態(tài),跳轉(zhuǎn)執(zhí)行步驟5;否則,繼續(xù)執(zhí)行步驟4。
步驟4繼續(xù)輸入im,同時記錄im信息到隊列中,判斷此時輸出是否為om。如果輸出是om,說明此時由于im的作用,協(xié)議實體的狀態(tài)已經(jīng)是sj,則執(zhí)行步驟5;否則,對于正常的輸入im沒有得到期望響應(yīng)報文om,說明協(xié)議實體可能出現(xiàn)異常,可能是停止響應(yīng)或者狀態(tài)異常遷移,保存隊列內(nèi)輸入報文信息,進(jìn)一步分析調(diào)試。
步驟5首先判斷狀態(tài)sj是否為OTP的終止?fàn)顟B(tài),如果是OTP的終止?fàn)顟B(tài),那么執(zhí)行步驟6,否則,判斷狀態(tài)sj是否為狀態(tài)機M的終止?fàn)顟B(tài);如果狀態(tài)sj是終止?fàn)顟B(tài),此時清空隊列內(nèi)所有已記錄的報文信息,因為需要重新建立新的會話,舊會話階段輸入的報文對新會話的測試沒有影響,然后返回步驟1重復(fù)該方法對狀態(tài)sj和其下一個狀態(tài)之間的遷移進(jìn)行操作;否則,直接返回步驟1對狀態(tài)sj和其下一個狀態(tài)之間的遷移進(jìn)行操作。
步驟6由OTP遷移標(biāo)記過程可知,可能某兩個狀態(tài)之間的遷移沒有被標(biāo)記,導(dǎo)致存在遷移未能被測試。此時,為了解決這種漏測問題,還需對未被測試的遷移進(jìn)行補充測試,參考2.1節(jié)介紹的方法,輸入前置引導(dǎo)序列將協(xié)議實體置于相應(yīng)狀態(tài),再輸入未測試過的狀態(tài)遷移相應(yīng)測試用例,檢測協(xié)議實體是否異常。如果所有狀態(tài)遷移都被測試,那么以O(shè)TP的始發(fā)狀態(tài)作為狀態(tài)si,返回至步驟1開始新一輪測試。
以圖1的FTP協(xié)議狀態(tài)機測試為例,對每個狀態(tài)遷移都進(jìn)行一次測試,需要向協(xié)議實體輸入的報文依次是~i1、i1|-、~i2、i2|-、~i3、i3|-、~i4、i4|-、~i5、i5|-、~i7、i7|-、~i11、i11|-、~i3、i3|-、~i4、i4|-、~i6、i6|-、~i10、i10|-、~i9、i9|-、~i3、i3|-、~i4、i4|-、~i6、i6|-、~i8、i8|-、~i3、i3|-、~i4、i4|-、~i5、i5|-、~i7、i7|-、~i12、i12|-。其中“|”表示選擇關(guān)系,“-”表示不輸入報文,如i1|-表示輸入i1或者不輸入報文。輸入該測試序列至多需要發(fā)送報文42次,最少需要交互21次,其中有21個測試用例進(jìn)行測試,完成一次所有狀態(tài)遷移的測試。
如果在進(jìn)行測試時,協(xié)議實體出現(xiàn)異常,如協(xié)議實體出現(xiàn)內(nèi)存訪問錯誤,或者達(dá)到一定條件,如測試用例數(shù)目或者時間達(dá)到上限,則停止測試。協(xié)議實體異??赡苁亲詈筝斎氲臏y試用例所觸發(fā),也可能是前期測試用例引發(fā)協(xié)議實體狀態(tài)異常遷移在此時才被檢測出來。例如,當(dāng)協(xié)議實體處于OPT上第一個s3狀態(tài)時,發(fā)送i4后并未返回期望響應(yīng)報文o4,可能是內(nèi)存錯誤等問題導(dǎo)致協(xié)議實體停止服務(wù),也可能是協(xié)議實體此時出現(xiàn)狀態(tài)異常遷移,也可能是s3狀態(tài)(對應(yīng)UIO序列是i4)測試后出現(xiàn)狀態(tài)異常遷移,還可能是OPT上第一個s2狀態(tài)(對應(yīng)UIO序列是(i3,i4))測試后出現(xiàn)狀態(tài)異常遷移。因此,在發(fā)現(xiàn)協(xié)議實體出現(xiàn)異常時,需要對保存前期輸入報文信息進(jìn)行分析,驗證捕獲協(xié)議實體異常是否為誤報,并進(jìn)一步分析異常原因,判斷是否存在可利用的漏洞。
總體而言,本章動態(tài)地調(diào)整后續(xù)輸入的報文類型,避免無效的報文交互,利用交叉迭代思想減少報文交互次數(shù),進(jìn)而提高測試效率。在每次輸入測試用例或者正常報文之后,對協(xié)議實體的響應(yīng)報文進(jìn)行分析,依據(jù)分析結(jié)果調(diào)整后續(xù)的輸入是測試用例還是正常報文。如果后續(xù)輸入是測試用例,那么又可以測試下一個遷移;如果后續(xù)輸入是正常報文,那么充當(dāng)前置引導(dǎo)序列的一部分,將協(xié)議實體引導(dǎo)至下一個狀態(tài)繼續(xù)測試,同時充當(dāng)某些狀態(tài)的UIO序列的一部分,達(dá)到檢測協(xié)議實體是否發(fā)生狀態(tài)異常遷移的目的。例如,基于FTP協(xié)議狀態(tài)機進(jìn)行測試時,正常報文i4是狀態(tài)s2和s3的UIO序列一部分,可用于檢測協(xié)議實體是否發(fā)生狀態(tài)異常遷移,i4又可作為狀態(tài)s4、s5或者s6的前置引導(dǎo)序列的一部分,i4的一次輸入實際上發(fā)揮多個作用,減少了報文交互次數(shù)。
Peach3.0是目前較為成熟的模糊測試框架,RFSMFuzzing是目前對有狀態(tài)協(xié)議進(jìn)行模糊測試的完整測試方案。本文方法PSTT-Fuzzing將與Peach3.0和RFSMFuzzing進(jìn)行對比,三種方法采用的測試用例均以Peach 3.0變異策略生成,測試用例有效性相同。選取兩種代表性的有狀態(tài)協(xié)議作為測試對象——FTP與SMTP協(xié)議,其對應(yīng)的協(xié)議實體程序信息如表3所示。
表3 測試對象的版本信息
首先對實際環(huán)境下的測試效率進(jìn)行評估,再以挖掘漏洞效率與挖掘能力統(tǒng)計結(jié)果進(jìn)行對比分析。
5.2.1 測試效率評估
在測試過程中,即便是發(fā)送測試用例總數(shù)與發(fā)送報文的總數(shù)的比值很高,測試效率也未必高。因為如果測試用例未能與協(xié)議狀態(tài)相對應(yīng),測試用例難以觸發(fā)協(xié)議實體異常,僅僅考慮發(fā)送測試用例總數(shù)與發(fā)送報文總數(shù)的比值還不能準(zhǔn)確評估測試效率。為了準(zhǔn)確評估測試效率,本文引入有效測試報文發(fā)送效率概念。
假設(shè)某個測試用例~in對應(yīng)于狀態(tài)si,當(dāng)協(xié)議實體處于被測狀態(tài)si時,輸入~in進(jìn)行測試,那么稱該測試用例~in為有效完成測試的測試用例。有效測試報文發(fā)送效率是指向被測協(xié)議實體輸入有效完成測試的測試用例個數(shù)與發(fā)送報文的總數(shù)的比值,以β表示有效測試報文發(fā)送效率,∑Ac表示有效完成測試的測試用例總數(shù),∑mj表示發(fā)送報文的總數(shù),β的數(shù)學(xué)表達(dá)式為β=∑Ac/∑mj。β值越大,說明發(fā)送輔助類型的報文越少,單位時間輸入與狀態(tài)相對應(yīng)的測試用例數(shù)量比值較高,測試效率越高,采用β評估測試效率更具有合理性。
以Quick’n Easy FTP Server作為FTP協(xié)議的被測協(xié)議實體,以Quick’n Easy Mail Server作為SMTP協(xié)議的被測協(xié)議實體。PSTT-Fuzzing、Peach3.0、與RFSMFuzzing有效完成測試的測試用例總數(shù)(即∑Ac)與時間的關(guān)系如圖6所示。
由圖可知,在任意時刻PSTT-Fuzzing方法對應(yīng)的有效完成測試用例數(shù)均要高于Peach3.0與RFSM-Fuzzing。Peach3.0盡管在測試時報文交互效率較高,單位時間輸出的測試用例數(shù)量較多,但是Peach輸入報文時盲目性較大,很多測試用例發(fā)送至協(xié)議實體時,協(xié)議實體狀態(tài)實際上并未與測試用例相對應(yīng),∑Ac值相對較低。RFSM-Fuzzing盡管采用完善的引導(dǎo)機制,使得多數(shù)測試用例可以在協(xié)議實體處于對應(yīng)狀態(tài)進(jìn)行測試,但是測試期間前置引導(dǎo)序列等輔助報文的比重大,時間耗費大,在單位時間內(nèi)的測試用例數(shù)目較少,∑Ac值也相對較低。PSTT-Fuzzing在分析響應(yīng)報文時存在時間耗費,但是該方法使用更少的交互引導(dǎo)報文,使得測試用例可在對應(yīng)狀態(tài)有效地實施測試,單位時間內(nèi)有效完成測試用例比重更大,∑Ac值更高。測試用例未能真正有效地實現(xiàn)測試。
圖6 有效完成測試用例數(shù)與測試時間的關(guān)系
需要說明的是,實際網(wǎng)絡(luò)環(huán)境、服務(wù)器性能會影響報文傳輸?shù)男剩虼擞行瓿蓽y試用例數(shù)∑Ac值和時間的關(guān)系具有一定的隨機性。為了更客觀地評估測試效率,表4列出測試5小時有效測試報文發(fā)送效率β的統(tǒng)計結(jié)果。
表4 5小時報文交互有效率統(tǒng)計 %
由表4可知,PSTT-Fuzzing對應(yīng)的β高于Peach3.0與RFSM-Fuzzing對應(yīng)的β。當(dāng)向協(xié)議實體發(fā)送報文的總數(shù)∑mj相同時,相同的網(wǎng)絡(luò)環(huán)境與服務(wù)器性能,發(fā)送時間耗費大致相同。由β的數(shù)學(xué)表達(dá)式可知,PSTTFuzzing對應(yīng)有效完成測試的測試用例總數(shù)∑Ac更高。
5.2.2 漏洞挖掘效果
漏洞挖掘效率是指挖掘相同的漏洞所需時間耗費,時間耗費越少挖掘效率越高;漏洞挖掘能力是指在模糊測試正常執(zhí)行條件下挖掘漏洞的數(shù)目。測試時間為5小時,漏洞挖掘效果統(tǒng)計結(jié)果如表5所示。
從表5可知,PSTT-Fuzzing漏洞挖掘能力和挖掘效率好于Peach與RFSM-Fuzzing。PSTT-Fuzzing挖掘出6個漏洞,Peach3.0挖掘出5個漏洞,RFSM-Fuzzing挖掘出4個漏洞,挖掘每個漏洞對應(yīng)的時間耗費,PSTT-Fuzzing均要低于其他兩種對比方法。
在挖掘能力方面,PSTT-Fuzzing效果好于Peach3.0與RFSM-Fuzzing。對于Quick Easy FTP Server V4.0.0服務(wù)器第二個未知漏洞,當(dāng)變異的PASV報文發(fā)送至服務(wù)器時,服務(wù)器反饋命令錯誤的提示,然后輸入正常PASV報文,在輸入變異的LIST報文,再輸入正常LIST報文時,服務(wù)器未返回任何響應(yīng)報文,經(jīng)檢測此時服務(wù)器已經(jīng)停止服務(wù);Peach與RFSM-Fuzzing兩種方法并未能挖掘該漏洞。對于Quick’n Easy Mail Server已知漏洞1,服務(wù)器短時間內(nèi)接收到一定數(shù)量包含長字符串參數(shù)的多個HELO命令的報文時,程序本身沒有錯誤提示,調(diào)試工具也未能捕獲到運行異常,但是服務(wù)器未返回期望響應(yīng)報文,經(jīng)檢測發(fā)現(xiàn)服務(wù)器已近停止服務(wù),Peach與RFSM-Fuzzing測試方法使用調(diào)試器檢測異常未能挖掘到該漏洞。在挖掘效率方面,從實驗統(tǒng)計結(jié)果對比可知,PSTT-Fuzzing的測試效率高于Peach與RFSMFuzzing方法,驗證了5.2.1小節(jié)測試性能評估的正確性。對測試性能與挖掘漏洞效果進(jìn)行比較,相比于Peach與RFSM-Fuzzing測試方法,本文測試方法PSTT-Fuzzing具有明顯的優(yōu)勢,本文模糊測試優(yōu)化方法達(dá)到了預(yù)期的測試效果。
本文針對現(xiàn)有的有狀態(tài)協(xié)議的模糊測試技術(shù)測試時存在輔助類型報文交互時間比重大,測試效率低下,測試覆蓋率低等問題,提出一種基于協(xié)議狀態(tài)遷移遍歷的模糊測試優(yōu)化方法。實驗結(jié)果表明,在相同測試時間情形下,本文方法可以針對性地發(fā)送更多測試用例,更易觸發(fā)協(xié)議程序異常,測試效率更高。下一步研究將提高測試用例的有效性,結(jié)合本文優(yōu)化方法,更好地提高模糊測試效率。
表5 5小時漏洞挖掘效果統(tǒng)計結(jié)果 min