葛子毅, 程紹銀, 蔣 凡
(中國科學(xué)技術(shù)大學(xué) 信息安全測評(píng)中心,安徽 合肥 230027)
指紋提取是進(jìn)行協(xié)議識(shí)別、網(wǎng)絡(luò)管控、流量計(jì)費(fèi)等工作的前提。協(xié)議的指紋[1]包括以下幾類:端口[2]、應(yīng)用層載荷特征[3]、基于流量的統(tǒng)計(jì)特征、傳輸層行為特征[4]等。其中,應(yīng)用層載荷特征具有應(yīng)用范圍廣、識(shí)別率高的優(yōu)點(diǎn),目前研究的比較多,但多集中在如何利用其進(jìn)行高速識(shí)別網(wǎng)絡(luò)流量方面[5]。針對(duì)應(yīng)用層載荷特征的生成問題研究得較少,工業(yè)界主要是依賴于人工分析網(wǎng)絡(luò)流量獲得該類特征,效率低下,準(zhǔn)確性差,且在協(xié)議升級(jí)時(shí)無法及時(shí)更新指紋。
文中提出一種基于程序不變量的應(yīng)用層載荷特征提取方法,該方法具有能夠自動(dòng)生成協(xié)議指紋,不需要分析協(xié)議的語法語義,生成的指紋精確性高等特點(diǎn)。
該方法是一種基于程序分析的方法,方法框架如圖1所示。
首先對(duì)輸入的網(wǎng)絡(luò)數(shù)據(jù)包進(jìn)行污點(diǎn)標(biāo)記,記錄數(shù)據(jù)包中各字段所處的位置。網(wǎng)絡(luò)應(yīng)用程序?qū)⑦@些數(shù)據(jù)包作為輸入,讀取并進(jìn)行后續(xù)處理。系統(tǒng)通過插樁控制模塊對(duì)應(yīng)用程序處理數(shù)據(jù)包的過程進(jìn)行插樁,根據(jù)定制化的配置文件決定插樁時(shí)機(jī)、位置和插入的分析代碼等。在插樁后的應(yīng)用程序動(dòng)態(tài)執(zhí)行的過程中,系統(tǒng)可以收集程序運(yùn)行時(shí)的狀態(tài),并且跟蹤經(jīng)過污點(diǎn)標(biāo)記的數(shù)據(jù)包中字段的傳播路徑,分別生成程序狀態(tài)集和污點(diǎn)傳播記錄。對(duì)程序狀態(tài)集進(jìn)行不變量檢測,獲得在動(dòng)態(tài)執(zhí)行過程中的程序不變量。對(duì)污點(diǎn)傳播記錄進(jìn)行過濾,得到精簡化的污點(diǎn)傳播軌跡。由于程序不變量與網(wǎng)絡(luò)數(shù)據(jù)包中字段間的關(guān)系存在對(duì)應(yīng),通過分析程序不變量中的有關(guān)變量值的污點(diǎn)傳播路徑,可以反推得到網(wǎng)絡(luò)數(shù)據(jù)包中各個(gè)字段間的固定關(guān)系,從而獲得網(wǎng)絡(luò)應(yīng)用程序的通信指紋。
圖1 基于程序不變量的指紋提取方法框架
(1)污點(diǎn)標(biāo)記
基于標(biāo)記的動(dòng)態(tài)污點(diǎn)傳播技術(shù)是指在程序運(yùn)行過程中,將應(yīng)用程序接收到的數(shù)據(jù)包的每個(gè)字節(jié)(污染數(shù)據(jù))進(jìn)行唯一性標(biāo)記,標(biāo)記的方法可以有很多種,其中最簡單的方法是按照每個(gè)字節(jié)在協(xié)議數(shù)據(jù)包中的偏移量進(jìn)行標(biāo)記,如圖2所示。
圖2 對(duì)某個(gè)HTTP數(shù)據(jù)包污點(diǎn)標(biāo)記示意
(2)配置導(dǎo)入
配置導(dǎo)入是一個(gè)可選用的部分,主要用途是在對(duì)應(yīng)用程序進(jìn)行插樁時(shí)進(jìn)行過濾,只對(duì)關(guān)注的程序段插樁,對(duì)已有庫函數(shù)和系統(tǒng)調(diào)用等不進(jìn)行插樁,減輕插樁分析的開銷。
(3)插樁控制
程序插樁是指在程序源代碼/二進(jìn)制代碼中插入分析語句,以使得在程序動(dòng)態(tài)運(yùn)行時(shí)獲取變量值、內(nèi)存狀態(tài)、函數(shù)調(diào)用等信息。
對(duì)于程序源代碼的插樁,即在源代碼中的合適位置,插入與程序源代碼兼容的程序語句,然后對(duì)包含插樁代碼的源代碼進(jìn)行編譯執(zhí)行。對(duì)于沒有源代碼的二進(jìn)制程序插樁,還可分為靜態(tài)插樁和動(dòng)態(tài)插樁。靜態(tài)插樁是在程序運(yùn)行前,通過改寫二進(jìn)制文件本身進(jìn)行插樁,可使用的工具有ATOM[6]等;動(dòng)態(tài)插樁是在程序運(yùn)行時(shí)根據(jù)程序的位置和實(shí)時(shí)狀態(tài)插入特定分析代碼,針對(duì)性強(qiáng),并且可以處理動(dòng)態(tài)生成的代碼,可采用的動(dòng)態(tài)二進(jìn)制程序插樁工具有PIN[7]等。動(dòng)態(tài)程序插樁開銷比較大,因此其插樁控制部分要著重提高效率,減少不必要的插樁開銷。如在圖1中所示,插樁控制模塊根據(jù)配置信息決定何時(shí)啟動(dòng)插樁,并根據(jù)具體指令的不同語義插樁不同的樁程序。
(4)動(dòng)態(tài)執(zhí)行
動(dòng)態(tài)執(zhí)行即是使插樁后的應(yīng)用程序?qū)嶋H運(yùn)行,同時(shí)收集程序運(yùn)行時(shí)的狀態(tài)和污點(diǎn)傳播情況。在有源代碼情況下,程序狀態(tài)集指的是源程序中各個(gè)變量在不同時(shí)刻的值,還可以包括函數(shù)調(diào)用軌跡,函數(shù)的參數(shù)值、返回值等。在二進(jìn)制條件下,程序狀態(tài)集指的是寄存器狀態(tài)和內(nèi)存狀態(tài),還包括具體執(zhí)行的指令、庫函數(shù)和系統(tǒng)調(diào)用等。在應(yīng)用程序的運(yùn)行過程中,對(duì)程序狀態(tài)集進(jìn)行跟蹤和更新。
(5)程序不變量檢測
不變量檢測模塊負(fù)責(zé)從動(dòng)態(tài)執(zhí)行過程生成的程序狀態(tài)集中提取出程序不變量。
對(duì)于二進(jìn)制程序,通過分析程序狀態(tài)集中與不變量生成密切相關(guān)的指令,可以快速得到與協(xié)議指紋有關(guān)的程序不變量。與通信指紋有關(guān)的不變量主要是一些域變量之間的相等關(guān)系或線性關(guān)系。線性關(guān)系是一些簡單的函數(shù)關(guān)系,比如a=strlen(b)。如果檢測到存在這種 strlen函數(shù)關(guān)系,則可以得到域 a是域b的長度的結(jié)論。有些匯編指令本身就具有這種strlen函數(shù)關(guān)系,比如對(duì)rep指令,ECX寄存器存放的要復(fù)制的字符串的長度,ESI寄存器存放的是源字符串的首地址。若ESI和ECX分別代表著協(xié)議數(shù)據(jù)包中的不同的域,則可以得到這兩個(gè)域之間存在的滿足 strlen函數(shù)的不變量關(guān)系。而對(duì)于有源代碼的應(yīng)用程序,可以利用已有不變量檢測工具(如Daikon[8])對(duì)程序狀態(tài)集中的變量間關(guān)系進(jìn)行檢查,自動(dòng)提取出程序不變量。
(6)污點(diǎn)傳播過濾
污點(diǎn)傳播記錄非常龐雜,可通過程序切片技術(shù),剔除不可能影響某個(gè)所關(guān)心變量值的程序執(zhí)行片段,從而將影響該變量值的程序執(zhí)行片段限定到一個(gè)較小的范圍中,以加快指紋生成模塊的分析速度。
(7)指紋生成
對(duì)于二進(jìn)制程序,程序的語義信息主要由一些特殊指令和庫函數(shù)引入。比如在cmp指令中,如果將協(xié)議中某個(gè)字段的污染標(biāo)簽反復(fù)與一個(gè)立即數(shù)比較,則該字段可能是控制循環(huán)次數(shù)的長度信息,從而可以認(rèn)為該字段表示長度信息,結(jié)合該字段的污染標(biāo)簽的傳播軌跡,即可推導(dǎo)出網(wǎng)絡(luò)數(shù)據(jù)包中的某字段的語義信息。一些庫函數(shù)本身也帶有很重要的語義信息,比如內(nèi)存拷貝函數(shù)memcpy,三個(gè)參數(shù)分別表示目的地址,源地址和要拷貝的長度。如果由污染傳播軌跡知道,第二個(gè)參數(shù)(源地址)是協(xié)議中某個(gè)字段的地址,且第三個(gè)參數(shù)(長度)是協(xié)議中某個(gè)字段的值,則可以很輕易的得到這兩個(gè)字段之間存在著不變量關(guān)系。指紋生成模塊即是根據(jù)對(duì)這一類特殊指令和庫函數(shù)的歸納和總結(jié),對(duì)程序狀態(tài)集中的記錄進(jìn)行檢索和分析,結(jié)合污點(diǎn)傳播信息,推導(dǎo)出數(shù)據(jù)包中的域間不變關(guān)系,獲得通信指紋。
對(duì)于有源代碼的應(yīng)用程序,程序的語義信息比較清晰,記錄由不變量檢測得到的程序不變量中所涉及到的變量,在污點(diǎn)傳播軌跡中查找這些變量的值的污點(diǎn)傳播來源,即可推導(dǎo)出數(shù)據(jù)包中的域間不變關(guān)系,獲得通信指紋。
圖3 BitTorrent握手?jǐn)?shù)據(jù)包
本節(jié)結(jié)合一個(gè)例子進(jìn)行說明,旨在闡釋本方法的思想。
BitTorrent是一款P2P下載軟件, 其最初版本的源代碼是用python語言編寫的。該例中,所使用的BitTorrent源碼版本為4.0.1,因?yàn)槭菍?duì)于源代碼插樁分析,目標(biāo)比較明確,因此為提高插樁效率所使用的配置文件等可以忽略。本例將BitTorrent握手?jǐn)?shù)據(jù)包作為上述方法中所涉及的網(wǎng)絡(luò)數(shù)據(jù)包,提取的協(xié)議指紋是該握手?jǐn)?shù)據(jù)包中應(yīng)用層載荷第0-19個(gè)字節(jié)“19BitTorrent protocol”。BitTorrent的握手?jǐn)?shù)據(jù)包如圖3所示。
(1)污點(diǎn)標(biāo)記
圖3中示出的部分為BitTorrent握手?jǐn)?shù)據(jù)包中的數(shù)據(jù)。從圖中可知BitTorrent握手?jǐn)?shù)據(jù)包中應(yīng)用層載荷前的數(shù)據(jù)為“19BitTorrent Protocol”。將BitTorrent握手?jǐn)?shù)據(jù)包中的數(shù)據(jù)以字節(jié)為單位分組,按照每個(gè)字節(jié)在網(wǎng)絡(luò)數(shù)據(jù)包中的偏移量對(duì) BitTorrent握手?jǐn)?shù)據(jù)包中的每組數(shù)據(jù)進(jìn)行污點(diǎn)標(biāo)記,這樣握手?jǐn)?shù)據(jù)包中的應(yīng)用層載荷第一個(gè)字節(jié)“19”的污染標(biāo)記為0,“BitTorrent Protocol”的污染標(biāo)記就為1-19。
(2)配置導(dǎo)入
由于BitTorrent的源碼比較簡單,很容易確定插樁的時(shí)機(jī)和位置,插樁的開銷也很低,因此本例中省略了配置導(dǎo)入的過程。
(3)插樁控制
首先分析源代碼,發(fā)現(xiàn) encoder.py負(fù)責(zé)發(fā)起對(duì)等客戶之間的連接,而connecter.py文件是負(fù)責(zé)分析連接數(shù)據(jù)包而后建立起對(duì)等連接,其中的_read_messages()是專門用來處理連接時(shí)接收到的握手?jǐn)?shù)據(jù)包。其部分代碼段如下:
上述代碼中yield n是從變量self._message中讀出n個(gè)字節(jié)。BitTorrent握手?jǐn)?shù)據(jù)包內(nèi)容以固定字符串“19BitTorrent protocol”開頭,其中19代表的是len(protocol_name),protocol_name即為“BitTorrent protocol”??梢娺@段代碼的功能就是識(shí)別接收到的數(shù)據(jù)包是否為BitTorrent握手?jǐn)?shù)據(jù)包。
為記錄程序運(yùn)行時(shí)的狀態(tài)信息,對(duì)以上源代碼段進(jìn)行插樁,加入輸出語句,輸出程序動(dòng)態(tài)執(zhí)行時(shí)的變量值,輸出的變量為 self._message1(yield 1時(shí)self._message的值)、self._message2(yield len((protocol_name)時(shí) self._message的值)、protocol_name、len(protocol_name)。進(jìn)行程序插樁后的代碼為:
(4)動(dòng)態(tài)執(zhí)行
編譯執(zhí)行插樁后的源代碼,輸出程序狀態(tài)集(本例中比較簡單,即是在程序不同位置以上變量的值),包括:self._message1、self._message2、len(protocol_name)和 protocol_name。
(5)不變量檢測
通過對(duì)上述插樁代碼輸出的結(jié)果作不變量檢測,可得到程序不變量關(guān)系 self._message1=len(protocol_name)=19,self._message2=protocol_name =“BitTorrent protocol”,也即存在程序不變量關(guān)系 self._message1=len(self._message2),且 self._message1 為常量“19”,self._message2 為常量“BitTorrent protocol”。
(6)污點(diǎn)傳播過濾
本例中通過對(duì)源代碼的分析,僅關(guān)注了可能與指紋相關(guān)的一些變量值的污點(diǎn)傳播過程,所產(chǎn)生的污點(diǎn)傳播記錄非常簡單,因此不需要污點(diǎn)傳播過濾的過程。
(7)指紋生成
對(duì)握手?jǐn)?shù)據(jù)包中字段作污染傳播分析。通過代碼分析數(shù)據(jù)包字節(jié)如何構(gòu)成變量 self._message的值,即污染數(shù)據(jù)如何傳播到變量self._message中。Connector.py文件中 data_came_in函數(shù)正是負(fù)責(zé)從數(shù)據(jù)包中讀取內(nèi)容存入到self._message中。如以下代碼段所示。
由此,被標(biāo)記的數(shù)據(jù)便從BitTorrent握手?jǐn)?shù)據(jù)包中傳播到self._message變量中。由于BitTorrent握手?jǐn)?shù)據(jù)包比較小,在一個(gè)循環(huán)內(nèi)“BitTorrent protocol”的污染標(biāo)記 1-20也傳播到 self._message的前20個(gè)字節(jié)處。
BitTorrent握手?jǐn)?shù)據(jù)包中污染標(biāo)記為0的一組數(shù)據(jù)的軌跡為“19”>> self._message >> self._message1,污染標(biāo)記為1-19的數(shù)據(jù)的污染傳播軌跡是相同的,都 為 “BitTorrent protocol” >> self._message >>self._message2。
由過程(5)已知程序不變量為self._message1=len(self._message2)且均為常量,再根據(jù)污點(diǎn)傳播記錄中的self._message1與BitTorrent握手?jǐn)?shù)據(jù)包中的“19”相關(guān)聯(lián),self._message2與BitTorrent握手?jǐn)?shù)據(jù)包中的“BitTorrent protocol”相關(guān)聯(lián),即得到BitTorrent應(yīng)用程序的通信指紋可以為:應(yīng)用層載荷第0-20個(gè)字節(jié)內(nèi)容為常量“19BitTorrent protocol”。
事實(shí)上,在WireShark中,也是以“19BitTorrent protocol”固定字符串作為BitTorrent協(xié)議指紋的,從而可知文中提出的指紋提取方法是有效的。
文中提出一種基于程序不變量的指紋提取方法,給出了該方法的步驟框架和具體模塊的闡述。并結(jié)合BitTorrent的實(shí)例,進(jìn)一步說明了該方法如何提取出有效的應(yīng)用層載荷特征指紋。該方法不需分析協(xié)議語法語義,且生成的指紋精確性高。
[1] DAINOTTI A,PESCAPè A,CLAFFY C K.Issues and Future Directions in Traffic Classification[J]. Network,IEEE , 2012,26(01):35-40.
[2] 周江,賈茂林,朱修陽,等.P2P應(yīng)用識(shí)別的研究[J].信息安全與通信保密,2009(09):96-97.
[3] 鄧偉鋒,程紹銀,蔣凡,等.應(yīng)用層負(fù)載特征定義及自動(dòng)提取方法[J].通信技術(shù),2012,45(07):20-23.
[4] 龍坤,陳庶樵,夏軍波.P2P網(wǎng)絡(luò)聚合流量識(shí)別技術(shù)研究[J].通信技術(shù),2010,43(01):142-144.
[5] 陳曙暉.基于內(nèi)容分析的高速網(wǎng)絡(luò)協(xié)議識(shí)別技術(shù)研究[D].長沙:國防科學(xué)技術(shù)大學(xué),2007.
[6] AMITABH S, ALAN E.ATOM: a System for Building Customized Program Analysis Tools[C]//Proceedings of the ACM SIGPLAN 1994 conference on Programming language design and implementation.ACM Press:New York,1994:196-205.
[7] LUK C K, COHN R, MUTH R, et al. Pin: Building Customized Program Analysis Tools with Dynamic Instrumentation[C]//Proc. Of the 2005 ACM Conference on Programming Language Design and Implementation(PLDI ’05). New York, NY, USA: ACM,2005:190-200.
[8] The Daikon Invariant Detector[EB/OL].Program Analysis Group of MIT[2012-10-31]. http://groups.csail.mit.edu/pag/daikon/.