陳家浩 王軼駿 呂 誠
(上海交通大學(xué)網(wǎng)絡(luò)空間安全學(xué)院 上海 200240)
隨著全球網(wǎng)絡(luò)服務(wù)爆發(fā)式的增長,網(wǎng)絡(luò)安全問題也隨之而來。大量的網(wǎng)絡(luò)攻擊腳本在網(wǎng)上傳播使用,對網(wǎng)絡(luò)健康生態(tài)造成了極大的威脅。而在針對網(wǎng)絡(luò)攻擊的檢測與防御中,網(wǎng)絡(luò)流量樣本是非常重要的研究對象和判斷依據(jù)。因此對各種網(wǎng)絡(luò)攻擊腳本所能產(chǎn)生的攻擊流量的采集工作就非常重要。
想要采集這些攻擊流量主要有4種方法:(1)使用真實(shí)的攻擊代碼對測試靶機(jī)進(jìn)行攻擊,攻擊流量直接由運(yùn)行的攻擊代碼生成;(2)對各類攻擊行為的特征進(jìn)行整理和建模,提取關(guān)鍵信息,構(gòu)造攻擊流量;(3)從真實(shí)的網(wǎng)絡(luò)安全事件分析與審計(jì)中獲得攻擊流量;(4)采用符號(hào)執(zhí)行技術(shù),對攻擊腳本進(jìn)行分析,提取其釋放的攻擊流量。
第1種方法通過直接運(yùn)行攻擊腳本的方式來產(chǎn)生攻擊流量。這種方法雖然可以得到最真實(shí)的攻擊流量,但存在明顯的缺點(diǎn):首先,不同攻擊代碼所使用的編程語言和運(yùn)行平臺(tái)各不相同,難以設(shè)計(jì)一套測試系統(tǒng)能夠運(yùn)行所有攻擊代碼,并釋放攻擊流量,這對研究人員需具備的硬件設(shè)施條件和個(gè)人能力有很高的要求;其次,一次成功的攻擊不僅僅依賴于攻擊方,對目標(biāo)也有很多的要求,為了提取在各種場景下的攻擊流量,需要模擬各種情況搭建多個(gè)滿足要求的靶機(jī)環(huán)境,網(wǎng)絡(luò)設(shè)備與網(wǎng)絡(luò)服務(wù)種類繁多,應(yīng)用場景復(fù)雜多變,搭建靶機(jī)環(huán)境的人力和物力成本非常大;再者,運(yùn)行攻擊代碼將會(huì)對實(shí)驗(yàn)系統(tǒng)和實(shí)驗(yàn)設(shè)備造成難以控制的破壞,甚至可能留下后門、木馬等長久性威脅。
第2種方法通過對各類攻擊行為對特征進(jìn)行整理和建模。這種方法需要通過各種途徑采集攻擊流量,才能對這些流量加以分析,提取有效數(shù)據(jù),根據(jù)模型生成仿真的攻擊流量。這個(gè)方法的缺點(diǎn)在于:首先,在不搭建靶機(jī)的情況下對攻擊流量的采集比較困難,很難對各類攻擊的流量進(jìn)行完整采集;其次,這種方法生成的仿真攻擊流量的可靠性取決于模型的準(zhǔn)確性,為了模擬真實(shí)攻擊流量,需要在數(shù)據(jù)包順序、流量分布特征等多方面進(jìn)行模擬,要想逼真地模仿在各種場景下的各類攻擊流量難度很大。
第3種方法通過從真實(shí)的網(wǎng)絡(luò)安全事件中獲取攻擊流量。這種方法不適合進(jìn)行大規(guī)模的采集工作。因?yàn)椴⒉皇蔷W(wǎng)絡(luò)安全事件的被攻擊方都愿意向研究者提供攻擊事件相關(guān)的信息,有的網(wǎng)絡(luò)安全攻擊事件還會(huì)被受害方主動(dòng)隱藏。并且這方法也看運(yùn)氣,很難在一段時(shí)間內(nèi)發(fā)生種類全面的網(wǎng)絡(luò)安全事件。
第4種方法使用符號(hào)執(zhí)行技術(shù)對攻擊腳本進(jìn)行靜態(tài)分析。這種方法也存在一定的缺點(diǎn),受限于攻擊腳本使用的編程語言,針對用不同編程語言編寫的攻擊腳本需要分別實(shí)現(xiàn)其符號(hào)執(zhí)行引擎。該方法帶來的優(yōu)勢就比較明顯,由于是靜態(tài)分析,無需搭建大量靶機(jī)環(huán)境,也無需采集各類攻擊流量,符號(hào)執(zhí)行技術(shù)會(huì)遍歷攻擊腳本的幾乎所有分支,生成各種情況下完整的攻擊流量,而且可以實(shí)現(xiàn)自動(dòng)化執(zhí)行,方便高效,極大地節(jié)約了人力物力成本。同時(shí)本文還發(fā)現(xiàn)目前很大一部分網(wǎng)絡(luò)攻擊腳本都使用Python語言作為腳本語言。
本文研究了一種對現(xiàn)有網(wǎng)絡(luò)攻擊腳本使用符號(hào)執(zhí)行的攻擊流量提取方案,通過該方案可以高效提取所需的攻擊流量。本文也會(huì)進(jìn)一步對其實(shí)際效果進(jìn)行分析。
符號(hào)執(zhí)行最初提出是在20世紀(jì)70年代中期,主要描述的是靜態(tài)復(fù)合執(zhí)行的原理,到了2005年左右由于引入了一些新的技術(shù)讓符號(hào)執(zhí)行更加實(shí)用,因而開始逐步流行。Concolic執(zhí)行的提出讓符號(hào)執(zhí)行真正成為可實(shí)用的程序分析技術(shù),其在對桌面應(yīng)用程序的測試中被廣泛研究。它能以最少的測試用例達(dá)到最高測試覆蓋率的特點(diǎn)受到廣大測試研究人員的青睞,進(jìn)而大量用于軟件測試、逆向工程等領(lǐng)域。
在2005年左右涌現(xiàn)出很多此方面的研究成果,Berkeley 大學(xué)提出的Kudzu Javascript 符號(hào)執(zhí)行平臺(tái),用于檢測 Javascript中的注入漏洞;MIT提出用于檢測HTML運(yùn)行時(shí)錯(cuò)誤的符號(hào)執(zhí)行工具 Apollo; UC Santa Barbara 和他們的CTF團(tuán)隊(duì)Shellphish提出的angr二進(jìn)制符號(hào)執(zhí)行平臺(tái)等。
目前符號(hào)執(zhí)行引擎主要分為三類:第一類用來分析x86二進(jìn)制機(jī)器碼,例如 UC Santa Barbara 和他們的CTF團(tuán)隊(duì)Shellphish提出的angr等;第二類用來分析基于LLVM項(xiàng)目的中間代碼,如2008年Cristian Cadar開發(fā)的KLEE等;第三類為專用符號(hào)執(zhí)行引擎,這些引擎往往針對特定的編程語言,如Berkeley 大學(xué)提出的Kudzu和MIT提出的Apollo。有些通用的符號(hào)執(zhí)行引擎雖然擴(kuò)展性好,可以支持多種編程語言,但執(zhí)行效率偏低;專用引擎雖然其限制較多,但是執(zhí)行效率高、實(shí)用性強(qiáng)。
此外,符號(hào)執(zhí)行技術(shù)的發(fā)展是依賴于求解器技術(shù)的發(fā)展的。求解器作為符號(hào)執(zhí)行技術(shù)的關(guān)鍵一環(huán),只有能夠求解復(fù)雜的路徑約束問題才能使符號(hào)執(zhí)行技術(shù)真正有實(shí)用價(jià)值。而近年來許多求解能力出眾的求解器逐漸出現(xiàn),其中以2015年微軟開源的Z3求解器最為著名。該求解器不但在求解能力上克服了多種原本業(yè)內(nèi)無法解決的非線性問題,還支持大量的編程語言API。
目前支持Python的符號(hào)執(zhí)行引擎有PyExZ3、CHEF。PyExZ3是專門針對Python的符號(hào)執(zhí)行引擎,使用z3 SMT求解器,現(xiàn)在只支持對整數(shù)類型的符號(hào)執(zhí)行,局限性較大;CHEF基于S2E引擎,由此衍生出來的符號(hào)執(zhí)行引擎,CHEF引擎作為通用性平臺(tái),具有擴(kuò)展性好、兼容性強(qiáng)的特點(diǎn),但所付出的代價(jià)就是執(zhí)行效率的低下。
從目前國內(nèi)外的相關(guān)研究來看,基于Python語言的符號(hào)執(zhí)行引擎存在局限性較大,缺乏實(shí)用價(jià)值,或者平臺(tái)體積龐大,執(zhí)行效率低下。因此本文介紹一套經(jīng)過改進(jìn)的以Python的符號(hào)執(zhí)行引擎為核心的方案,可以用于對攻擊流量的提取。
本文在研究過程中發(fā)現(xiàn),使用符號(hào)執(zhí)行技術(shù)進(jìn)行自動(dòng)流量采集工作的方案并不是僅僅依靠符號(hào)執(zhí)行技術(shù)就能實(shí)現(xiàn)的。網(wǎng)絡(luò)上流傳的Python攻擊腳本形式參差不齊,需要合理統(tǒng)一的預(yù)處理流程把它們的結(jié)構(gòu)統(tǒng)一到一個(gè)合理的標(biāo)準(zhǔn)上才能使得之后的符號(hào)執(zhí)行過程穩(wěn)定運(yùn)行。因此本文的方案設(shè)計(jì)如圖1所示。本節(jié)介紹的預(yù)處理部分的流程如圖2所示。
圖1 方案總體結(jié)構(gòu)設(shè)計(jì)圖
圖2 腳本預(yù)處理流程圖
網(wǎng)絡(luò)攻擊腳本通常都會(huì)與目標(biāo)設(shè)備進(jìn)行大量業(yè)務(wù)邏輯的交互。原因主要有:
(1) 不同種類的網(wǎng)站服務(wù)之間業(yè)務(wù)差距巨大,交互方式的差異甚至遠(yuǎn)遠(yuǎn)超過兩臺(tái)不同品牌不同系統(tǒng)的電腦,并且能同時(shí)攻擊兩種不同的網(wǎng)絡(luò)設(shè)備的漏洞少之又少。因此,針對網(wǎng)絡(luò)服務(wù)的攻擊腳本一開始需要檢查目標(biāo)網(wǎng)絡(luò)設(shè)備的型號(hào),通過向其交互后獲得的反饋數(shù)據(jù)進(jìn)行判斷。
(2) 設(shè)備的固件版本與該設(shè)備存在的漏洞情況關(guān)系非常大,因此攻擊腳本一開始需要對目標(biāo)網(wǎng)絡(luò)服務(wù)的版本進(jìn)行檢查,根據(jù)目標(biāo)設(shè)備的返回?cái)?shù)據(jù)來判斷出目標(biāo)設(shè)備是否存在漏洞。
(3) 由于大部分網(wǎng)絡(luò)服務(wù)的漏洞存在于業(yè)務(wù)邏輯交互中,因此讓漏洞點(diǎn)暴露出來需要一定的業(yè)務(wù)交互鋪墊。這其中會(huì)涉及到在函數(shù)體內(nèi)部使用變量保存反饋數(shù)據(jù)內(nèi)容,再根據(jù)這些內(nèi)容進(jìn)行判斷,進(jìn)入分支代碼。
基于以上原因,本階段需要尋找到這些保存著反饋數(shù)據(jù)的變量,這些變量在后續(xù)的代碼中往往會(huì)以字符串的形式進(jìn)行判斷跳轉(zhuǎn)。因此需要將這些變量原本的獲取內(nèi)容進(jìn)行劫持,使這些外來的數(shù)據(jù)也加入后續(xù)的符號(hào)執(zhí)行。
最初本文進(jìn)行如下的嘗試:(1) 去除該變量獲取數(shù)據(jù)的那一行代碼;(2) 在目標(biāo)函數(shù)中添加該變量,使其成為這個(gè)函數(shù)的一個(gè)字符串輸入?yún)?shù)。如圖3所示。
圖3 變量添加示意圖一
這個(gè)方法從符號(hào)執(zhí)行技術(shù)的角度來說完全可行,符號(hào)執(zhí)行階段會(huì)將該變量作為一個(gè)符號(hào)變量進(jìn)行推算,從而遍歷執(zhí)行到受它影響的代碼分支。但是,這個(gè)方法對于本文所需的流量采集目的來說是不可行的。因?yàn)槿コ撟兞客ㄟ^網(wǎng)絡(luò)交互而獲取數(shù)據(jù)的代碼后,本次符號(hào)執(zhí)行所得的流量中自然就會(huì)缺少這行代碼原本應(yīng)該產(chǎn)生的交互流量。因此,本文采用了新的改進(jìn)方案,如圖4所示。
圖4 變量添加示意圖二
該方案中依然保留了獲取網(wǎng)絡(luò)數(shù)據(jù)的代碼,但是在其下方立刻補(bǔ)了一條賦值語句。將賦值語句中的右操作數(shù)變量作為函數(shù)的參數(shù)寫入函數(shù)參數(shù)列表。這樣一來,就依然能夠執(zhí)行這一網(wǎng)絡(luò)交互動(dòng)作產(chǎn)生相應(yīng)的網(wǎng)絡(luò)流量,但是也可以使得符號(hào)執(zhí)行對該內(nèi)容進(jìn)行后續(xù)的推算。
同時(shí)也存在攻擊腳本中沒有主函數(shù),直接使用Python代碼執(zhí)行的情況,此時(shí)需要先將這部分代碼包裹入自定義的無參數(shù)主函數(shù)。
通常網(wǎng)絡(luò)攻擊腳本中需要指定目標(biāo)的IP與端口,有時(shí)也需要指定攻擊者的IP與端口。這兩種變量通常不會(huì)參與后續(xù)的條件判斷,而是直接在之后的代碼中被使用,因此并不需要參與符號(hào)執(zhí)行。
此外,IP地址這種類型的變量雖然通常為一個(gè)字符串,但是由于腳本中缺乏對IP地址的判斷約束,導(dǎo)致IP地址變量幾乎不可能被符號(hào)執(zhí)行引擎推算成“XXX.XXX.XXX.XXX”的形式。
因此,IP變量與PORT變量并不適合使用符號(hào)執(zhí)行進(jìn)行處理,需要在預(yù)處理階段將其預(yù)先設(shè)定好。設(shè)定方案如下:通過匹配 “host”、“ip”、“port”、“parser”等關(guān)鍵字來找出腳本中的這些變量。通常它們會(huì)以3種形式出現(xiàn):
(1) 函數(shù)參數(shù)列表中的參數(shù)。
(2) 全局變量。
(3) 需要用戶輸入的parser參數(shù)。
第一種情況下,先將這些變量從參數(shù)列表中移除,然后在函數(shù)一開始就將這些變量設(shè)定為指定的IP和PORT值,如圖5所示。
圖5 變量預(yù)設(shè)示意圖一
第二種情況下,直接將這些全局變量賦值為指定的IP和PORT值,如圖6所示。
圖6 變量預(yù)設(shè)示意圖二
將這些變量設(shè)置為固定值也是為了幫助后續(xù)的流量采集。通過過濾指定IP和PORT的流量包來精準(zhǔn)地采集該腳本的流量,去除別的噪聲流量。
第三種情況與以上處理方法類似,直接將目標(biāo)變量賦值即可。
在一個(gè)Python語言寫的網(wǎng)絡(luò)攻擊腳本中,通常會(huì)有許多函數(shù),符號(hào)執(zhí)行階段需要對其中某個(gè)涵蓋了全部攻擊邏輯的主函數(shù)進(jìn)行符號(hào)執(zhí)行。尋找這個(gè)函數(shù)的任務(wù)也應(yīng)當(dāng)由預(yù)處理階段來完成。
目前采用的方案是:將腳本文件名(不包括拓展名)進(jìn)行統(tǒng)一編號(hào)和重命名。然后將目標(biāo)主函數(shù)的聲明處和調(diào)用處也進(jìn)行重命名,并且主函數(shù)重命名后的名稱和腳本文件名(不包括拓展名)保持一致。這樣符號(hào)執(zhí)行引擎可以根據(jù)文件名來找到該腳本中的主函數(shù)。
通常網(wǎng)絡(luò)攻擊腳本中的主函數(shù)是main()函數(shù)、run()、exploit()函數(shù)等。本項(xiàng)目中對其處理的策略是exploit()函數(shù)優(yōu)先。方案如下:
(1) 將攻擊腳本重命名為“expXXXXXXXXXX.py”的形式。
(2) 尋找是否存在exploit()函數(shù),如果存在,則將該函數(shù)重命名為“expXXXXXXXXXX()”的名稱,并相應(yīng)地修改原本調(diào)用exploit()的代碼,然后結(jié)束本處理。
(3) 尋找是否存在run()函數(shù),如果存在,則將該函數(shù)重命名為“expXXXXXXXXXX()”的名稱,并相應(yīng)地修改原本調(diào)用run()的代碼,然后結(jié)束本處理。
(4) 尋找代碼中是否存在指定主函數(shù)的“if __name__==‘__main__’”語句,如果存在,則將其中唯一包含的函數(shù)重命名為“expXXXXXXXXXX()”的名稱,并相應(yīng)地修改原本調(diào)用該函數(shù)(通常為main函數(shù))的代碼。
此方案的效果如圖7-圖8所示。
圖7 腳本重命名示意圖一
圖8 腳本重命名示意圖二
網(wǎng)絡(luò)上可以獲得的用Python寫的網(wǎng)絡(luò)攻擊腳本所使用的Python版本是不同的,有的使用Python 2,有的使用Python 3。需要將其統(tǒng)一為Python 3下可運(yùn)行的腳本。
這一步通過使用Python 3的官方工具2to3即可實(shí)現(xiàn)轉(zhuǎn)換化。轉(zhuǎn)換過程中如果出現(xiàn)報(bào)錯(cuò)信息需要傳遞給空白數(shù)據(jù)填寫階段。轉(zhuǎn)化成功后為了確保該腳本的正確性,需要在Python 3環(huán)境下執(zhí)行一下。如果執(zhí)行失敗需要記錄報(bào)錯(cuò)信息并傳遞給空白數(shù)據(jù)填寫階段。
本階段與之前的三個(gè)預(yù)處理階段只處理一次不同,其對于一個(gè)攻擊腳本來說可能需要和空白數(shù)據(jù)填寫操作進(jìn)行反復(fù)循環(huán),流程如圖9所示。
圖9 腳本適配流程圖
許多網(wǎng)絡(luò)攻擊腳本中是需要自定義參數(shù)的,例如IP、端口、地址偏移等。有些腳本會(huì)有默認(rèn)的參數(shù)使得該腳本在沒有被用戶根據(jù)實(shí)際情況修改前依然可以正常運(yùn)行。但依然有相當(dāng)一部分腳本中沒有默認(rèn)值而導(dǎo)致腳本無法正常運(yùn)行起來。
沒有默認(rèn)值的變量在代碼中的形式通常有如下兩種:
(1) 這些變量的預(yù)設(shè)值在代碼中是一串字符,用來提示使用者修改這里。如:“offset=YOUR_TARGET_OFFSET”
(2) 預(yù)設(shè)值是提示符如:“a=*****”。
本文的處理方法是使用“循環(huán)報(bào)錯(cuò)法”。這個(gè)方法涉及到腳本適配和空白數(shù)據(jù)填寫兩個(gè)階段的循環(huán)執(zhí)行。通過腳本適配階段的報(bào)錯(cuò)信息來發(fā)現(xiàn)以上的兩種情況:
(1) 當(dāng)報(bào)錯(cuò)中含有error type 36等信息時(shí),說明是變量賦值時(shí)遇到了如“****”的提示符。此時(shí),將產(chǎn)生報(bào)錯(cuò)信息代碼行的右操作數(shù)改成合法數(shù)值即可。
(2) 當(dāng)腳本適配的嘗試運(yùn)行中出現(xiàn)報(bào)錯(cuò),如果報(bào)錯(cuò)信息是“undefined”相關(guān),則說明是遇到了“offset=YOUR_TARGET_OFFSET”這類賦值。此時(shí)Python執(zhí)行環(huán)境會(huì)誤將右操作數(shù)理解成了一個(gè)未定義的變量。因此,根據(jù)報(bào)錯(cuò)信息中的問題代碼行數(shù)即可自動(dòng)修改該行代碼的右操作數(shù)為實(shí)際數(shù)值,從而使得腳本運(yùn)行無誤。
由于報(bào)錯(cuò)是一個(gè)個(gè)出現(xiàn)的,因此本階段會(huì)與腳本適配階段循環(huán)執(zhí)行,直到腳本適配階段不報(bào)錯(cuò)后,該腳本的預(yù)處理即處理完成,流程如圖10所示。
圖10 空白數(shù)據(jù)填寫流程圖
為了更好地展示預(yù)處理階段對整個(gè)方案的重要性和突出的實(shí)踐效果,本文在此挑選出一個(gè)需要用到上文全部預(yù)處理手段的實(shí)際攻擊腳本來對比其預(yù)處理前后的變化。預(yù)處理前的攻擊腳本如圖11所示。
圖11 預(yù)處理前的樣例攻擊腳本
由圖11可知,該攻擊腳本原本的文件名稱為“CVE-2018-18067-Exploit.py”,使用Python2進(jìn)行編寫。在該攻擊腳本中存在著等待修改的目標(biāo)IP變量,等待預(yù)設(shè)的用戶TOKEN變量,還有涉及網(wǎng)絡(luò)交互的變量。
而圖12中則是預(yù)處理后的腳本,此時(shí)其已經(jīng)被翻譯成了符合Python3語法標(biāo)準(zhǔn)的腳本。上文提到的各類變量都已經(jīng)在預(yù)處理的各個(gè)階段被處理,圖中的方框指出了修改的部分,腳本的文件名也已經(jīng)與符號(hào)執(zhí)行的目標(biāo)函數(shù)名保持了一致。預(yù)處理后的腳本就可以順利進(jìn)入之后的符號(hào)執(zhí)行步驟。
圖12 預(yù)處理后的攻擊腳本
本節(jié)為整個(gè)方案的核心階段,腳本代碼的遍歷執(zhí)行、流量的采集都在本階段進(jìn)行。
本文雖然有高效的Pyexz3項(xiàng)目作為支撐,但是該項(xiàng)目在Python字符串的符號(hào)執(zhí)行技術(shù)方面完全是空白,故本文進(jìn)行了大量的改進(jìn)與研發(fā)。
本文參考并使用了微軟公司所開發(fā)的一套Python 3符號(hào)執(zhí)行引擎。該框架是Python符號(hào)執(zhí)行領(lǐng)域開源項(xiàng)目中的佼佼者。
Pyexz3引擎的效率很高,但是文檔和代碼的可讀性較差。該引擎底層使用的求解器是微軟的另一個(gè)開源項(xiàng)目Z3求解器。該求解器幾乎是領(lǐng)域內(nèi)效果最好的求解器,但是文檔管理依然糟糕,3.3節(jié)中的求解示例由本文總結(jié),并未出現(xiàn)在官方文檔中。
目前Pyexz3只能對整數(shù)變量進(jìn)行符號(hào)執(zhí)行,不支持字符串變量的符號(hào)執(zhí)行計(jì)算。而本文對于字符串變量的符號(hào)執(zhí)行需求遠(yuǎn)遠(yuǎn)高于整數(shù)變量。因此本文在保留Pyexz3基本架構(gòu)的情況下對其進(jìn)行了大量改進(jìn),以增添字符串符號(hào)執(zhí)行的能力,改進(jìn)后的項(xiàng)目命名為Pyexz3P。
根據(jù)Pyexz3現(xiàn)有的架構(gòu),Pyexz3P項(xiàng)目對字符串符號(hào)執(zhí)行功能的設(shè)計(jì)結(jié)構(gòu)如圖13所示。
圖13 字符串符號(hào)執(zhí)行系統(tǒng)架構(gòu)設(shè)計(jì)圖
本結(jié)構(gòu)最大程度地利用了Pyexz3項(xiàng)目本身在處理整數(shù)符號(hào)執(zhí)行時(shí)的結(jié)構(gòu),繼承了其高效、層次分明的優(yōu)勢。
本結(jié)構(gòu)中使用SymbolicStr類來參與本符號(hào)執(zhí)行引擎的約束條件計(jì)算。當(dāng)約束條件計(jì)算完成后,會(huì)集中整理并保存進(jìn)入新的代碼分支所需要的全部約束條件集合Predicate實(shí)例中。
本結(jié)構(gòu)中使用Z3String類來對之前整理保存的約束條件集合進(jìn)行轉(zhuǎn)化。把現(xiàn)有的約束條件轉(zhuǎn)化為一條條Z3求解器可以理解的求解判斷規(guī)則。如此一來,求解器的接口和符號(hào)執(zhí)行邏輯就能分離開來,方便以后拓展更多高性能的求解器。
PathToConstraint類一方面是收集約束條件的核心類,另一方面也是選擇代碼路徑的核心選擇器。在微軟原本的項(xiàng)目中使用的是BFS樹結(jié)構(gòu)遍歷算法。這個(gè)選擇對于普通大型Python項(xiàng)目來說是合理的,因?yàn)檫@類項(xiàng)目的代碼邏輯中分支代碼之間有大量并列關(guān)系,隨著約束分支深度的上升,求解的約束集合也會(huì)增大,此時(shí)求解器求解失敗導(dǎo)致符號(hào)執(zhí)行引擎失敗的概率也會(huì)上升。因此使用廣度優(yōu)先算法來處理約束樹可以優(yōu)先探索并列的代碼邏輯,較快測試到各個(gè)并列的功能。
對本文而言,BFS算法則并不適合,因?yàn)镻ython攻擊腳本普遍邏輯簡單,并列的功能分支較少,主要攻擊邏輯相比于其他檢測邏輯在深度上要高出許多。因此,需要優(yōu)先使用DFS算法來更快地進(jìn)入真正的攻擊邏輯分支。故本文對約束遍歷的算法進(jìn)行了改進(jìn)。
本文使用了FunctionInvocation類與ExplorationEngine類進(jìn)行實(shí)際的腳本代碼執(zhí)行。這就使得符號(hào)執(zhí)行引擎在遍歷代碼分支的同時(shí)已經(jīng)真正地執(zhí)行了攻擊腳本的代碼并產(chǎn)生了對應(yīng)的攻擊流量,而無需根據(jù)符號(hào)執(zhí)行所得的求解去重新執(zhí)行采集。
根據(jù)以上設(shè)計(jì),本文將其中各個(gè)部分所需要的代碼實(shí)現(xiàn)后,就可以使得Pyexz3P對字符串相關(guān)的判斷約束語句進(jìn)行識(shí)別和加載。接下來所要做的就是在各個(gè)約束條件被加載后的分析并轉(zhuǎn)化成Z3求解器能理解的形式。
3.3.1 字符串長度的約束處理
在網(wǎng)絡(luò)攻擊腳本中由于存在payload這樣的對于數(shù)據(jù)長度敏感的內(nèi)容,因此對于數(shù)據(jù)長度的要求有時(shí)會(huì)比反饋數(shù)據(jù)的內(nèi)容更加重要。
要想實(shí)現(xiàn)對于字符串長度的約束條件計(jì)算,首先要先弄清最后的轉(zhuǎn)化目標(biāo)——Z3求解器中相應(yīng)的求解表達(dá)式。經(jīng)過查閱官方文檔和代碼后,本文總結(jié)了一個(gè)示例如圖14所示。
圖14 字符串長度約束Z3構(gòu)造示例圖
由此可見,需要將代碼中長度相關(guān)的約束條件轉(zhuǎn)化為一個(gè)操作數(shù)數(shù)量為1,操作符為“str.len”的expression類實(shí)例。然后轉(zhuǎn)化成Z3表達(dá)式階段將其轉(zhuǎn)化為“Length(z_l)”,其中z_l代表字符串取長度操作中唯一的左操作數(shù)。
3.3.2 字符串內(nèi)容的約束處理
在一些關(guān)鍵數(shù)據(jù)的判斷上,攻擊腳本會(huì)嚴(yán)格進(jìn)行字符串對比,這時(shí)候需要對字符串內(nèi)容的約束條件進(jìn)行求解表達(dá)式的轉(zhuǎn)化。
本文總結(jié)了兩個(gè)Z3求解器中關(guān)于字符串內(nèi)容的約束求解示例,如圖15所示。
圖15 字符串內(nèi)容約束Z3構(gòu)造示例圖
3.3.3 子字符串內(nèi)容的約束處理
在字符串的對比判斷中,子字符串占了一個(gè)很重要的角色。網(wǎng)絡(luò)數(shù)據(jù)中存在大量需要判斷數(shù)據(jù)格式、開頭的情景,因此,實(shí)現(xiàn)了對于從字符串中截取子字符串并進(jìn)行符號(hào)執(zhí)行的功能需求。
由于官方文檔在子字符串處理方面完全空白,本文總結(jié)了一個(gè)Z3求解器中關(guān)于子字符串內(nèi)容的約束求解示例,第一個(gè)示例如圖16所示。
圖16 子字符串內(nèi)容約束Z3構(gòu)造示例圖一
圖16的示例步驟在實(shí)際符號(hào)表達(dá)式解析時(shí)會(huì)過于繁瑣,因此,本文總結(jié)了另一個(gè)更適合符號(hào)執(zhí)行技術(shù)需求的示例,如圖17所示。
圖17 子字符串內(nèi)容約束Z3構(gòu)造示例圖二
該示例中可以精確控制子字符串在原字符串中的位置和長度,從而使求解器求解的答案更加精準(zhǔn)。并且從示例中argv1和argv2的關(guān)聯(lián)中可以看出,本方法能解決字符串變量傳遞的問題。
3.3.4 正則表達(dá)式的處理
在字符串的對比判斷中,有時(shí)會(huì)出現(xiàn)正則表達(dá)式的匹配判斷。目前網(wǎng)上已開源的針對各種語言的符號(hào)執(zhí)行引擎中,大部分都沒有處理正則表達(dá)式約束的能力。
本文先使用正則表達(dá)式反向推導(dǎo)來獲得一個(gè)符合該正則表達(dá)式的字符串,將這個(gè)正則匹配約束轉(zhuǎn)化為一個(gè)3.3.2節(jié)的字符串內(nèi)容約束或者3.3.3節(jié)的子字符串內(nèi)容約束。這樣一來就可以解決這一類正則匹配約束了。Python下有一個(gè)開源庫名叫xeger,該庫可以根據(jù)正則表達(dá)式來反向推算符合該正則的字符串。步驟如圖18所示。
圖18 正則表達(dá)式約束Z3構(gòu)造示例圖
在預(yù)處理中,本文將腳本中的IP和端口都設(shè)置為特定的值,這么做就是為了方便這個(gè)階段的流量采集工作。通過流量的目標(biāo)IP、目標(biāo)端口、本地IP和本地端口來過濾流量并抓取保存。由于符號(hào)執(zhí)行過程中幾乎每個(gè)代碼路徑都被執(zhí)行了一次,因此一個(gè)腳本中會(huì)產(chǎn)生多次流量。
本文對于每條執(zhí)行的代碼路徑進(jìn)行了代碼覆蓋率統(tǒng)計(jì),并且還綜合考慮了該條路徑最終產(chǎn)生的流量數(shù)據(jù)大小和Python調(diào)用API的次數(shù),通過加權(quán)計(jì)算的方式挑選出所需的流量。
由于代碼路徑搜索策略的選擇對符號(hào)執(zhí)行的最終效果有很大的影響,因此本文還需要考慮當(dāng)前需求下深度優(yōu)先搜索和廣度優(yōu)先搜索之間的選擇。
本文發(fā)現(xiàn)Pyexz3項(xiàng)目使用的路徑遍歷策略為深度優(yōu)先搜索,經(jīng)過仔細(xì)研究代碼發(fā)現(xiàn)該策略不是有意為之,而是該項(xiàng)目在路徑遍歷功能實(shí)現(xiàn)中很自然地優(yōu)先將新發(fā)現(xiàn)的分支約束加入約束棧,產(chǎn)生了先進(jìn)先出的效果。本文考慮到客觀情況:網(wǎng)絡(luò)攻擊腳本大多邏輯較為簡單,分支復(fù)雜的地方大多為攻擊腳本中反復(fù)發(fā)送或請求數(shù)據(jù)包的部分以及目標(biāo)環(huán)境檢測部分。
在反復(fù)發(fā)送或請求數(shù)據(jù)包的部分代碼中會(huì)出現(xiàn)循環(huán)次數(shù)較高的分支代碼,如果使用深度優(yōu)先策略會(huì)使得本方案難以跳出該循環(huán)從而引起路徑爆炸。這類情況一般DDOS、數(shù)據(jù)庫拖庫相關(guān)的攻擊腳本中出現(xiàn)較多,需要使用廣度優(yōu)先策略來解決這一問題。
在目標(biāo)環(huán)境檢測部分代碼中會(huì)出現(xiàn)大量的同級(jí)分支,類似于C語言中的switch邏輯。這時(shí)候使用廣度優(yōu)先策略會(huì)比深度優(yōu)先策略的效率低。但是本文在實(shí)踐中發(fā)現(xiàn)這并不會(huì)導(dǎo)致整個(gè)系統(tǒng)卡死,只是降低了平行跳轉(zhuǎn)邏輯的執(zhí)行效率而已。相比于上面的第一種情況中深度優(yōu)先策略會(huì)使整個(gè)系統(tǒng)困死在死循環(huán)中要好得多。
因此,本文中還改進(jìn)了這個(gè)深度優(yōu)先的遍歷效果,將其改為廣度優(yōu)先,從而使得本文的方案在可接受的性能犧牲下快速跳出一些容易導(dǎo)致路徑爆炸的循環(huán)分支,進(jìn)入真正的攻擊代碼邏輯中。
本階段為符號(hào)執(zhí)行階段的一個(gè)補(bǔ)救方案,并不是所有的攻擊腳本都會(huì)進(jìn)入本階段,只有當(dāng)符號(hào)執(zhí)行階段失敗后,才會(huì)將第一階段預(yù)處理后的標(biāo)準(zhǔn)腳本傳遞入本階段進(jìn)行最后的自動(dòng)采集流量嘗試。
由于符號(hào)執(zhí)行技術(shù)與求解器技術(shù)的發(fā)展限制,一些約束的求解是無法完成的,比如許多非線性問題、涉及HASH反推的問題。這些問題的求解方法在如今數(shù)學(xué)學(xué)科發(fā)展中依然是使用暴力枚舉的手段,會(huì)大大降低求解器的效率甚至超出其求解能力范圍。因此,符號(hào)執(zhí)行階段對某些攻擊腳本可能無法順利運(yùn)行。
只有遇到這樣的情況時(shí),才會(huì)進(jìn)入最后的自動(dòng)化獲取流量嘗試,對腳本進(jìn)行強(qiáng)制執(zhí)行處理。通過這種“偽符號(hào)執(zhí)行”的方法來代替特殊情況下的符號(hào)執(zhí)行需求,以此來擴(kuò)大可自動(dòng)化獲取攻擊腳本流量的覆蓋范圍。
強(qiáng)制執(zhí)行方法雖然較為粗暴,但是其在本項(xiàng)目中是為了彌補(bǔ)符號(hào)執(zhí)行技術(shù)的不足而設(shè)計(jì)的最后自動(dòng)化措施。故依然希望能夠盡可能保留代碼的執(zhí)行順序。于是本階段將會(huì)采用一個(gè)代碼樹的結(jié)構(gòu)來保存代碼段,并以父子節(jié)點(diǎn)的關(guān)系來表示前后執(zhí)行順序。
強(qiáng)制執(zhí)行的基本步驟歸納如下:
(1) 將攻擊腳本中的代碼以跳轉(zhuǎn)分支指令為分割點(diǎn),把腳本中的代碼分解成一個(gè)個(gè)代碼塊。
(2) 將這些代碼塊按照執(zhí)行順序存儲(chǔ)為樹結(jié)構(gòu)。
(3) 運(yùn)用樹的遍歷算法來根據(jù)代碼樹中的一條條代碼路徑生成新腳本并執(zhí)行采集流量。
代碼樹樣例如圖19所示。
圖19 代碼樹樣例圖
4.2.1 條件語句結(jié)構(gòu)
這類語句中存在著一段需要滿足一定條件才能執(zhí)行的語句。在強(qiáng)制執(zhí)行階段會(huì)將這段代碼取出后填入代碼樹中進(jìn)行強(qiáng)制執(zhí)行。結(jié)構(gòu)轉(zhuǎn)化如圖20所示。
圖20 條件語句結(jié)構(gòu)轉(zhuǎn)化圖
4.2.2 循環(huán)語句結(jié)構(gòu)
這類語句中存在著一段需要滿足一定條件就能反復(fù)執(zhí)行的語句。在強(qiáng)制執(zhí)行階段會(huì)將這段代碼取出后填入代碼樹中進(jìn)行強(qiáng)制執(zhí)行。結(jié)構(gòu)轉(zhuǎn)化如圖21所示。
圖21 循環(huán)語句結(jié)構(gòu)轉(zhuǎn)化圖
由于本文更注重代碼執(zhí)行的覆蓋率,因此循環(huán)的語句在代碼樹中僅需被執(zhí)行一次。這樣其中包含的攻擊流量就會(huì)順利生成并被采集,故無需反復(fù)執(zhí)行。
4.2.3 函數(shù)調(diào)用結(jié)構(gòu)
Python語言中通常的函數(shù)調(diào)用可以分為自定義函數(shù)調(diào)用和非自定義函數(shù)調(diào)用。非自定義函數(shù)是通過引入編程庫來調(diào)用的,本文無需關(guān)心這類函數(shù)的內(nèi)部實(shí)現(xiàn)。自定義函數(shù)是攻擊腳本中,腳本作者為了提高代碼模塊程度與可讀性而寫的,本文需要將這部分函數(shù)調(diào)用也在代碼樹中進(jìn)行分段存儲(chǔ)。結(jié)構(gòu)如圖22所示。
圖22 函數(shù)調(diào)用時(shí)的代碼樹基本結(jié)構(gòu)
由于自定義函數(shù)中也可能因存在條件跳轉(zhuǎn)等結(jié)構(gòu)而產(chǎn)生代碼樹分支。因此,自定義函數(shù)的子節(jié)點(diǎn)可能存在多個(gè),每個(gè)子節(jié)點(diǎn)后都連接著調(diào)用函數(shù)接下來的代碼段節(jié)點(diǎn),結(jié)構(gòu)如圖23所示。
圖23 函數(shù)調(diào)用時(shí)的代碼樹詳細(xì)結(jié)構(gòu)
從4.2節(jié)可以看出,代碼樹中存儲(chǔ)的代碼量在分支較多時(shí),會(huì)出現(xiàn)在不同節(jié)點(diǎn)上重復(fù)存儲(chǔ)同一代碼段的情況。這樣無疑會(huì)使得代碼數(shù)的存儲(chǔ)代碼量超過原本攻擊腳本的代碼量。
但是這些重復(fù)代碼段的情況對于本項(xiàng)目來說開銷并不大。因?yàn)榫W(wǎng)絡(luò)攻擊腳本的代碼量普遍較短,并且條件、循環(huán)結(jié)構(gòu)的使用較少,通常都是在檢測目標(biāo)設(shè)備型號(hào)時(shí)使用一次,其他部分使用較少。因此由上述條件、循環(huán)結(jié)構(gòu)產(chǎn)生的重復(fù)代碼存儲(chǔ)并不會(huì)造成存儲(chǔ)空間和代碼可能路徑的爆炸式增長。因此,本文使用以上方案是完全合適的。
通過在Exploit-DB等公開網(wǎng)站上獲取的網(wǎng)絡(luò)攻擊腳本來測試本套系統(tǒng)的運(yùn)行效果。
用于測試的攻擊腳本集需要能夠完整測試到符號(hào)執(zhí)行和強(qiáng)制執(zhí)行的功能而不能集中在序號(hào)執(zhí)行功能上。
在測試過程中采集到的流量需要與本項(xiàng)目研究人員針對相同腳本手工嗅探到的流量進(jìn)行對比。在對比過程中需要對流量的關(guān)鍵特征如數(shù)據(jù)包的時(shí)序特征、數(shù)據(jù)包內(nèi)容特征等進(jìn)行仔細(xì)比對,對于其中的差異要進(jìn)行分析。
本次測試使用下載到的一個(gè)針對MS08-067的攻擊腳本。先搭建一個(gè)運(yùn)行著未更新安全補(bǔ)丁的Windows7操作系統(tǒng)虛擬機(jī)作為其攻擊的靶機(jī)環(huán)境。
通過配置虛擬機(jī)網(wǎng)絡(luò)環(huán)境,將攻擊者IP和目標(biāo)IP分別調(diào)整至特定內(nèi)網(wǎng)IP。在攻擊端開啟Wireshark等網(wǎng)絡(luò)數(shù)據(jù)包嗅探工具,使用其自帶的過濾器對IP進(jìn)行過濾。手動(dòng)使用攻擊腳本對靶機(jī)進(jìn)行攻擊,從而獲得其在真實(shí)攻擊中所發(fā)出的攻擊流量,如表1所示。
表1 真實(shí)攻擊所捕獲的流量
接下來將此腳本通過本系統(tǒng)進(jìn)行處理,處理完成后,選擇了流量最多的那條代碼路徑。其所對應(yīng)的流量特征如數(shù)據(jù)表2所示。
表2 通過符號(hào)執(zhí)行所捕獲的流量
本系統(tǒng)產(chǎn)生的流量與真實(shí)攻擊過程中產(chǎn)生的網(wǎng)絡(luò)流量相似度很高,數(shù)據(jù)包之間的先后順序和數(shù)據(jù)內(nèi)容都與真實(shí)攻擊相符。
在數(shù)據(jù)包內(nèi)容和時(shí)序上已經(jīng)高度相似的基礎(chǔ)上,接下來進(jìn)一步查看其整體的流量特性。根據(jù)表1、表2中的數(shù)據(jù)進(jìn)一步畫出本系統(tǒng)產(chǎn)生的流量和實(shí)際攻擊中攻擊方產(chǎn)生的流量的時(shí)域分布圖,如圖24、圖25所示。
圖24 本系統(tǒng)采集的攻擊流量時(shí)間分布
圖25 實(shí)際攻擊流量的時(shí)間分布
5.3.1 誤差分析1
由圖24、圖25可看出,本系統(tǒng)產(chǎn)生的流量整體相似度非常高。這是因?yàn)榉?hào)執(zhí)行過程中帶入求解答案進(jìn)行執(zhí)行時(shí)運(yùn)行的代碼與真實(shí)攻擊中的代碼是完全一樣的。因此,產(chǎn)生的攻擊流量在內(nèi)容特征和時(shí)間特征上的相似度也會(huì)非常高。
不過可以看出,時(shí)間分布上有少量偏差。進(jìn)一步計(jì)算各個(gè)包的偏差值發(fā)現(xiàn)其具有明顯隨機(jī)性,故認(rèn)為這是由于網(wǎng)絡(luò)傳輸環(huán)境的變化而造成的正常誤差。
從兩幅圖的對比也可以看出,有少量折線點(diǎn)分布不同,即圖24中的第11點(diǎn)和圖25中的第12點(diǎn)附近。進(jìn)一步分析流量內(nèi)容可知,這部分?jǐn)?shù)據(jù)點(diǎn)為雙方網(wǎng)絡(luò)連接正常產(chǎn)生的數(shù)據(jù)包,與攻擊流量無關(guān),故可以忽略。
5.3.2 誤差分析2
由圖24、圖25可看出,本系統(tǒng)產(chǎn)生的流量在時(shí)域分布上雖然順序相同,但是時(shí)間間隔上出現(xiàn)了明顯的偏差。
于是本文更換了一個(gè)攻擊腳本進(jìn)行了多次對比實(shí)驗(yàn),在數(shù)據(jù)包內(nèi)容特征上依然相同,但是這次在時(shí)間間隔上出現(xiàn)了較大不同,如圖26-圖29所示。
圖26 對比實(shí)驗(yàn)一
圖27 對比實(shí)驗(yàn)二
圖28 對比實(shí)驗(yàn)三
圖29 對比實(shí)驗(yàn)四
經(jīng)過仔細(xì)分析,其原因?yàn)椋赫鎸?shí)攻擊中經(jīng)常需要等待被攻擊方的反饋來進(jìn)行下一步的攻擊,而本系統(tǒng)中將反饋?zhàn)兞糠?hào)化進(jìn)行求解計(jì)算,無需等待真實(shí)靶機(jī)反饋,故流量產(chǎn)生較快。
然而本文認(rèn)為攻擊數(shù)據(jù)包發(fā)送時(shí)間間隔縮小并不會(huì)影響其在各類安全產(chǎn)品中的測試效果。因?yàn)楫?dāng)前大部分威脅情報(bào)系統(tǒng)、防火墻等都主要根據(jù)數(shù)據(jù)包內(nèi)容進(jìn)行特征匹配,而數(shù)據(jù)包間隔受客觀網(wǎng)絡(luò)環(huán)境好壞影響而無法確定,故幾乎不考慮。因此,本文采集的攻擊流量依然有相當(dāng)高的研究價(jià)值。
本文收集了50個(gè)網(wǎng)絡(luò)上公開的Python攻擊腳本進(jìn)行測試,挑選這些腳本時(shí),盡可能優(yōu)先選擇較新的腳本。漏洞的種類涵蓋了遠(yuǎn)程破解、網(wǎng)絡(luò)應(yīng)用攻擊、拒絕服務(wù)攻擊等各個(gè)方面且數(shù)量平均。
用本文提出的方案對這些測試攻擊腳本進(jìn)行處理,觀察其符號(hào)執(zhí)行的實(shí)際效果。并且使用本文改進(jìn)的Pyexz3P項(xiàng)目與原本的Pyexz3項(xiàng)目進(jìn)行性能對比。
經(jīng)過測試,本文統(tǒng)計(jì)了各種特征的50個(gè)攻擊腳本的符號(hào)執(zhí)行效果,如表3所示。
表3 通過符號(hào)執(zhí)行所捕獲的流量
表3中,總共50個(gè)攻擊腳本,Pyexz3P成功執(zhí)行了49個(gè),僅僅在其中一個(gè)包含特殊形式參數(shù)的攻擊腳本上執(zhí)行失敗,但是強(qiáng)制執(zhí)行成功。而Pyexz3原項(xiàng)目則有20個(gè)攻擊腳本符號(hào)執(zhí)行失敗,個(gè)別腳本上還出現(xiàn)了多個(gè)錯(cuò)誤。最終統(tǒng)計(jì)出由于路徑爆炸而失敗2次,由于關(guān)鍵變量形式特殊而失敗4次,由于沒有主函數(shù)而失敗17次,由于沒有字符串符號(hào)執(zhí)行能力而失敗2次。
從結(jié)果數(shù)據(jù)中可以看出,本文的方案由于使用了廣度優(yōu)先算法而成功跳出了測試腳本中的2個(gè)包含100次以上循環(huán)結(jié)構(gòu)的攻擊腳本。而使用深度優(yōu)先策略則在這樣的大量循環(huán)結(jié)構(gòu)中難以逃脫。
本文在第2節(jié)中的預(yù)處理使得本文的方案在避免特殊形式參數(shù)、不規(guī)范的主函數(shù)上的能力大大提升。這也是直觀數(shù)據(jù)上本方案對原項(xiàng)目效果最明顯的改進(jìn),甚至超越了符號(hào)執(zhí)行技術(shù)本身。
雖然原項(xiàng)目僅僅因?yàn)樽址?hào)執(zhí)行的問題失敗了兩次,但是測試腳本中涉及字符串約束計(jì)算的攻擊腳本也只有兩個(gè)。因此其實(shí)本文在字符串符號(hào)執(zhí)行能力上的改進(jìn)是從無到有的大改進(jìn),并且也使本方案達(dá)到了工業(yè)可用的水平。
本文提出了一整套自動(dòng)化提取網(wǎng)絡(luò)攻擊Python腳本的流量收集方法。相比于一般針對腳本的符號(hào)執(zhí)行項(xiàng)目,本文注意到了對腳本的預(yù)處理在整個(gè)自動(dòng)化分析中的關(guān)鍵作用并詳細(xì)闡述了這個(gè)預(yù)處理過程中需要進(jìn)行的各項(xiàng)處理,從而使得本項(xiàng)目的穩(wěn)定性大大提高。
此外本文以符號(hào)執(zhí)行為自動(dòng)化提取流量的核心,同時(shí)也注意到了這項(xiàng)技術(shù)當(dāng)前客觀發(fā)展的不足而提出了強(qiáng)制執(zhí)行作為候補(bǔ)方案,從而極大地提高了本系統(tǒng)提取攻擊流量時(shí)的穩(wěn)定性與成功率。
在測試階段,本方案展示出了不俗的提取效果,所提取的網(wǎng)絡(luò)攻擊流量真實(shí)度很高,攻擊特征保留完好。并且符號(hào)執(zhí)行功能上的改進(jìn)也使得本方案的通用性和健壯性大大增強(qiáng)。對于之后的安全研究工作有著積極的推動(dòng)作用。
由于求解器技術(shù)的發(fā)展限制,一些約束問題的求解方法在當(dāng)前客觀的計(jì)算機(jī)算法科學(xué)或者數(shù)學(xué)科學(xué)發(fā)展程度下是無法求出合適答案的。因此,希望之后符號(hào)執(zhí)行領(lǐng)域或者求解器領(lǐng)域相關(guān)研究工作可以加入最新的求解算法來增強(qiáng)符號(hào)執(zhí)行引擎的求解能力,擴(kuò)大其可以處理的約束條件范圍。這個(gè)方向的發(fā)展進(jìn)步無疑可以在日后提高本項(xiàng)目中順利使用符號(hào)執(zhí)行進(jìn)行流量生成的腳本比例,同時(shí)降低生成流量效果較為遜色的強(qiáng)制執(zhí)行比例。
本文解決的是使用Python語言編寫的網(wǎng)絡(luò)攻擊腳本。盡管Python的確是大部分網(wǎng)絡(luò)攻擊腳本所使用的編程語言,但是也有許多網(wǎng)絡(luò)攻擊腳本使用了別的編程語言如Ruby語言。故希望有別的項(xiàng)目可以參考本文,對更多編程語言的攻擊腳本進(jìn)行自動(dòng)化分析與流量采集。
由于本文針對的對象是網(wǎng)絡(luò)攻擊腳本,因此其跳轉(zhuǎn)邏輯往往并不復(fù)雜,判斷語句所產(chǎn)生的約束條件也十分易于被當(dāng)前的求解器解決。因此,作為符號(hào)執(zhí)行引擎的補(bǔ)救方案——強(qiáng)制執(zhí)行,實(shí)際用到的比例較低。故對于這個(gè)補(bǔ)救方案并沒有做過多的優(yōu)化,因?yàn)檫@在本項(xiàng)目中的回報(bào)并不明顯。但是對于目前許多符號(hào)執(zhí)行引擎技術(shù)依然是空白的新編程語言來說,強(qiáng)制執(zhí)行是一個(gè)很好的候選方案。這個(gè)方案的技術(shù)入門門檻低,建設(shè)成本小,并且效果也能滿足大多數(shù)測試需求。因此,希望這個(gè)方案可以被其他項(xiàng)目參考選用并被優(yōu)化。