葛子毅, 程紹銀, 蔣 凡
(中國科學(xué)技術(shù)大學(xué) 信息安全測評中心,安徽 合肥 230027)
指紋提取是進行協(xié)議識別、網(wǎng)絡(luò)管控、流量計費等工作的前提。協(xié)議的指紋[1]包括以下幾類:端口[2]、應(yīng)用層載荷特征[3]、基于流量的統(tǒng)計特征、傳輸層行為特征[4]等。其中,應(yīng)用層載荷特征具有應(yīng)用范圍廣、識別率高的優(yōu)點,目前研究的比較多,但多集中在如何利用其進行高速識別網(wǎng)絡(luò)流量方面[5]。針對應(yīng)用層載荷特征的生成問題研究得較少,工業(yè)界主要是依賴于人工分析網(wǎng)絡(luò)流量獲得該類特征,效率低下,準(zhǔn)確性差,且在協(xié)議升級時無法及時更新指紋。
文中提出一種基于程序不變量的應(yīng)用層載荷特征提取方法,該方法具有能夠自動生成協(xié)議指紋,不需要分析協(xié)議的語法語義,生成的指紋精確性高等特點。
該方法是一種基于程序分析的方法,方法框架如圖1所示。
首先對輸入的網(wǎng)絡(luò)數(shù)據(jù)包進行污點標(biāo)記,記錄數(shù)據(jù)包中各字段所處的位置。網(wǎng)絡(luò)應(yīng)用程序?qū)⑦@些數(shù)據(jù)包作為輸入,讀取并進行后續(xù)處理。系統(tǒng)通過插樁控制模塊對應(yīng)用程序處理數(shù)據(jù)包的過程進行插樁,根據(jù)定制化的配置文件決定插樁時機、位置和插入的分析代碼等。在插樁后的應(yīng)用程序動態(tài)執(zhí)行的過程中,系統(tǒng)可以收集程序運行時的狀態(tài),并且跟蹤經(jīng)過污點標(biāo)記的數(shù)據(jù)包中字段的傳播路徑,分別生成程序狀態(tài)集和污點傳播記錄。對程序狀態(tài)集進行不變量檢測,獲得在動態(tài)執(zhí)行過程中的程序不變量。對污點傳播記錄進行過濾,得到精簡化的污點傳播軌跡。由于程序不變量與網(wǎng)絡(luò)數(shù)據(jù)包中字段間的關(guān)系存在對應(yīng),通過分析程序不變量中的有關(guān)變量值的污點傳播路徑,可以反推得到網(wǎng)絡(luò)數(shù)據(jù)包中各個字段間的固定關(guān)系,從而獲得網(wǎng)絡(luò)應(yīng)用程序的通信指紋。

圖1 基于程序不變量的指紋提取方法框架
(1)污點標(biāo)記
基于標(biāo)記的動態(tài)污點傳播技術(shù)是指在程序運行過程中,將應(yīng)用程序接收到的數(shù)據(jù)包的每個字節(jié)(污染數(shù)據(jù))進行唯一性標(biāo)記,標(biāo)記的方法可以有很多種,其中最簡單的方法是按照每個字節(jié)在協(xié)議數(shù)據(jù)包中的偏移量進行標(biāo)記,如圖2所示。

圖2 對某個HTTP數(shù)據(jù)包污點標(biāo)記示意
(2)配置導(dǎo)入
配置導(dǎo)入是一個可選用的部分,主要用途是在對應(yīng)用程序進行插樁時進行過濾,只對關(guān)注的程序段插樁,對已有庫函數(shù)和系統(tǒng)調(diào)用等不進行插樁,減輕插樁分析的開銷。
(3)插樁控制
程序插樁是指在程序源代碼/二進制代碼中插入分析語句,以使得在程序動態(tài)運行時獲取變量值、內(nèi)存狀態(tài)、函數(shù)調(diào)用等信息。
對于程序源代碼的插樁,即在源代碼中的合適位置,插入與程序源代碼兼容的程序語句,然后對包含插樁代碼的源代碼進行編譯執(zhí)行。對于沒有源代碼的二進制程序插樁,還可分為靜態(tài)插樁和動態(tài)插樁。靜態(tài)插樁是在程序運行前,通過改寫二進制文件本身進行插樁,可使用的工具有ATOM[6]等;動態(tài)插樁是在程序運行時根據(jù)程序的位置和實時狀態(tài)插入特定分析代碼,針對性強,并且可以處理動態(tài)生成的代碼,可采用的動態(tài)二進制程序插樁工具有PIN[7]等。動態(tài)程序插樁開銷比較大,因此其插樁控制部分要著重提高效率,減少不必要的插樁開銷。如在圖1中所示,插樁控制模塊根據(jù)配置信息決定何時啟動插樁,并根據(jù)具體指令的不同語義插樁不同的樁程序。
(4)動態(tài)執(zhí)行
動態(tài)執(zhí)行即是使插樁后的應(yīng)用程序?qū)嶋H運行,同時收集程序運行時的狀態(tài)和污點傳播情況。在有源代碼情況下,程序狀態(tài)集指的是源程序中各個變量在不同時刻的值,還可以包括函數(shù)調(diào)用軌跡,函數(shù)的參數(shù)值、返回值等。在二進制條件下,程序狀態(tài)集指的是寄存器狀態(tài)和內(nèi)存狀態(tài),還包括具體執(zhí)行的指令、庫函數(shù)和系統(tǒng)調(diào)用等。在應(yīng)用程序的運行過程中,對程序狀態(tài)集進行跟蹤和更新。
(5)程序不變量檢測
不變量檢測模塊負(fù)責(zé)從動態(tài)執(zhí)行過程生成的程序狀態(tài)集中提取出程序不變量。
對于二進制程序,通過分析程序狀態(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)系,比如對rep指令,ECX寄存器存放的要復(fù)制的字符串的長度,ESI寄存器存放的是源字符串的首地址。若ESI和ECX分別代表著協(xié)議數(shù)據(jù)包中的不同的域,則可以得到這兩個域之間存在的滿足 strlen函數(shù)的不變量關(guān)系。而對于有源代碼的應(yīng)用程序,可以利用已有不變量檢測工具(如Daikon[8])對程序狀態(tài)集中的變量間關(guān)系進行檢查,自動提取出程序不變量。
(6)污點傳播過濾
污點傳播記錄非常龐雜,可通過程序切片技術(shù),剔除不可能影響某個所關(guān)心變量值的程序執(zhí)行片段,從而將影響該變量值的程序執(zhí)行片段限定到一個較小的范圍中,以加快指紋生成模塊的分析速度。
(7)指紋生成
對于二進制程序,程序的語義信息主要由一些特殊指令和庫函數(shù)引入。比如在cmp指令中,如果將協(xié)議中某個字段的污染標(biāo)簽反復(fù)與一個立即數(shù)比較,則該字段可能是控制循環(huán)次數(shù)的長度信息,從而可以認(rèn)為該字段表示長度信息,結(jié)合該字段的污染標(biāo)簽的傳播軌跡,即可推導(dǎo)出網(wǎng)絡(luò)數(shù)據(jù)包中的某字段的語義信息。一些庫函數(shù)本身也帶有很重要的語義信息,比如內(nèi)存拷貝函數(shù)memcpy,三個參數(shù)分別表示目的地址,源地址和要拷貝的長度。如果由污染傳播軌跡知道,第二個參數(shù)(源地址)是協(xié)議中某個字段的地址,且第三個參數(shù)(長度)是協(xié)議中某個字段的值,則可以很輕易的得到這兩個字段之間存在著不變量關(guān)系。指紋生成模塊即是根據(jù)對這一類特殊指令和庫函數(shù)的歸納和總結(jié),對程序狀態(tài)集中的記錄進行檢索和分析,結(jié)合污點傳播信息,推導(dǎo)出數(shù)據(jù)包中的域間不變關(guān)系,獲得通信指紋。
對于有源代碼的應(yīng)用程序,程序的語義信息比較清晰,記錄由不變量檢測得到的程序不變量中所涉及到的變量,在污點傳播軌跡中查找這些變量的值的污點傳播來源,即可推導(dǎo)出數(shù)據(jù)包中的域間不變關(guān)系,獲得通信指紋。

圖3 BitTorrent握手?jǐn)?shù)據(jù)包
本節(jié)結(jié)合一個例子進行說明,旨在闡釋本方法的思想。
BitTorrent是一款P2P下載軟件, 其最初版本的源代碼是用python語言編寫的。該例中,所使用的BitTorrent源碼版本為4.0.1,因為是對于源代碼插樁分析,目標(biāo)比較明確,因此為提高插樁效率所使用的配置文件等可以忽略。本例將BitTorrent握手?jǐn)?shù)據(jù)包作為上述方法中所涉及的網(wǎng)絡(luò)數(shù)據(jù)包,提取的協(xié)議指紋是該握手?jǐn)?shù)據(jù)包中應(yīng)用層載荷第0-19個字節(jié)“19BitTorrent protocol”。BitTorrent的握手?jǐn)?shù)據(jù)包如圖3所示。
(1)污點標(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é)為單位分組,按照每個字節(jié)在網(wǎng)絡(luò)數(shù)據(jù)包中的偏移量對 BitTorrent握手?jǐn)?shù)據(jù)包中的每組數(shù)據(jù)進行污點標(biāo)記,這樣握手?jǐn)?shù)據(jù)包中的應(yīng)用層載荷第一個字節(jié)“19”的污染標(biāo)記為0,“BitTorrent Protocol”的污染標(biāo)記就為1-19。
(2)配置導(dǎo)入
由于BitTorrent的源碼比較簡單,很容易確定插樁的時機和位置,插樁的開銷也很低,因此本例中省略了配置導(dǎo)入的過程。
(3)插樁控制
首先分析源代碼,發(fā)現(xiàn) encoder.py負(fù)責(zé)發(fā)起對等客戶之間的連接,而connecter.py文件是負(fù)責(zé)分析連接數(shù)據(jù)包而后建立起對等連接,其中的_read_messages()是專門用來處理連接時接收到的握手?jǐn)?shù)據(jù)包。其部分代碼段如下:

上述代碼中yield n是從變量self._message中讀出n個字節(jié)。BitTorrent握手?jǐn)?shù)據(jù)包內(nèi)容以固定字符串“19BitTorrent protocol”開頭,其中19代表的是len(protocol_name),protocol_name即為“BitTorrent protocol”。可見這段代碼的功能就是識別接收到的數(shù)據(jù)包是否為BitTorrent握手?jǐn)?shù)據(jù)包。
為記錄程序運行時的狀態(tài)信息,對以上源代碼段進行插樁,加入輸出語句,輸出程序動態(tài)執(zhí)行時的變量值,輸出的變量為 self._message1(yield 1時self._message的值)、self._message2(yield len((protocol_name)時 self._message的值)、protocol_name、len(protocol_name)。進行程序插樁后的代碼為:

(4)動態(tài)執(zhí)行
編譯執(zhí)行插樁后的源代碼,輸出程序狀態(tài)集(本例中比較簡單,即是在程序不同位置以上變量的值),包括:self._message1、self._message2、len(protocol_name)和 protocol_name。
(5)不變量檢測
通過對上述插樁代碼輸出的結(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)污點傳播過濾
本例中通過對源代碼的分析,僅關(guān)注了可能與指紋相關(guān)的一些變量值的污點傳播過程,所產(chǎn)生的污點傳播記錄非常簡單,因此不需要污點傳播過濾的過程。
(7)指紋生成
對握手?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ù)包比較小,在一個循環(huán)內(nèi)“BitTorrent protocol”的污染標(biāo)記 1-20也傳播到 self._message的前20個字節(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ù)污點傳播記錄中的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個字節(jié)內(nèi)容為常量“19BitTorrent protocol”。
事實上,在WireShark中,也是以“19BitTorrent protocol”固定字符串作為BitTorrent協(xié)議指紋的,從而可知文中提出的指紋提取方法是有效的。
文中提出一種基于程序不變量的指紋提取方法,給出了該方法的步驟框架和具體模塊的闡述。并結(jié)合BitTorrent的實例,進一步說明了該方法如何提取出有效的應(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)用識別的研究[J].信息安全與通信保密,2009(09):96-97.
[3] 鄧偉鋒,程紹銀,蔣凡,等.應(yīng)用層負(fù)載特征定義及自動提取方法[J].通信技術(shù),2012,45(07):20-23.
[4] 龍坤,陳庶樵,夏軍波.P2P網(wǎng)絡(luò)聚合流量識別技術(shù)研究[J].通信技術(shù),2010,43(01):142-144.
[5] 陳曙暉.基于內(nèi)容分析的高速網(wǎng)絡(luò)協(xié)議識別技術(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/.