• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      面向漏洞類型的Crash分類研究

      2020-07-06 13:35:02代培武潘祖烈
      計算機(jī)工程與應(yīng)用 2020年13期
      關(guān)鍵詞:插樁污點(diǎn)二進(jìn)制

      代培武,潘祖烈,施 凡

      國防科技大學(xué) 電子對抗學(xué)院,合肥 230000

      1 引言

      互聯(lián)網(wǎng)的普及給人們帶來便利,惠及人們生活的各行各業(yè),但近些年發(fā)生的震網(wǎng)病毒、勒索病毒、棱鏡門事件等使人們意識到互聯(lián)網(wǎng)安全的重要性,軟件漏洞分析研究是計算機(jī)領(lǐng)域的熱點(diǎn)難點(diǎn)問題[1]。Fuzzing 技術(shù)通過自動或半自動的方法反復(fù)驅(qū)動目標(biāo)軟件運(yùn)行并為其提供構(gòu)造的輸入數(shù)據(jù),同時監(jiān)控軟件運(yùn)行的異常結(jié)果,能高效地產(chǎn)生Crash(程序異常或崩潰)[2],但該方法存在盲目性,產(chǎn)生的Crash數(shù)量巨大,只有極少數(shù)與漏洞成因有關(guān),逐個分析會耗費(fèi)研究人員大量時間,效率低下卻錯誤率較高。因此如何自動化地對Crash進(jìn)行分類和精簡是漏洞研究人員急需攻克的難題。

      在早期的軟件安全研究過程中,研究人員借助OllyDbg和C32Asm等調(diào)試器對二進(jìn)制代碼的整體結(jié)構(gòu)和模塊進(jìn)行手工分析,并在可知的執(zhí)行路徑上進(jìn)行相應(yīng)的實(shí)際跟蹤,這嚴(yán)重依賴分析人員的技術(shù)水平和經(jīng)驗(yàn)?zāi)芰?,誤判率較高。后來開發(fā)的Valgrind[3]、AddressSanitizer[4]等一些低級的內(nèi)存檢測工具通過錯誤路徑修改、增量分析、SAT 分析來發(fā)現(xiàn)導(dǎo)致系統(tǒng)崩潰的內(nèi)存錯誤、邏輯錯誤、指針錯誤等,但同樣存在效率和準(zhǔn)確率的問題。動態(tài)污點(diǎn)分析(Dynamic Taint Analysis)[5]通過標(biāo)記非信任數(shù)據(jù)來源,追蹤并記錄程序執(zhí)行過程中污點(diǎn)信息,檢測污點(diǎn)數(shù)據(jù)的非法使用,以達(dá)到獲取關(guān)鍵位置與輸入數(shù)據(jù)關(guān)聯(lián)信息的分析方法。2014年IEEE會議上,Zhang等人提出新型的二進(jìn)制可執(zhí)行程序崩潰分析框架ExpTracer[6]。該框架在二進(jìn)制插樁平臺Pin 上進(jìn)行開發(fā),使用基于污點(diǎn)分析的數(shù)據(jù)流引導(dǎo)分析技術(shù)直接對二進(jìn)制可執(zhí)行程序進(jìn)行分析,能夠識別二進(jìn)制可執(zhí)行程序潛在的漏洞并對Crash 進(jìn)行分類和可利用性判定,但效率低下。UC Berkely大學(xué)開發(fā)的BitBlaze[7]能通過二進(jìn)制可執(zhí)行程序污點(diǎn)分析來確定程序崩潰時哪些寄存器和內(nèi)存地址來自攻擊者控制的輸入文件,對NULL指針切片的同時查看指針起始位置來快速判定二進(jìn)制可執(zhí)行程序存在的漏洞類型和該Crash 是由何種類型漏洞引起的,但分析對象單一,只能對棧溢出進(jìn)行分析。李根等人研發(fā)的Hunter[8]和Wang 等人開發(fā)的TaintScope[9]利用污點(diǎn)類型和污點(diǎn)虛擬化技術(shù)對二進(jìn)制可執(zhí)行程序進(jìn)行漏洞檢測,但無法分析Crash。

      本文主要研究如何利用污點(diǎn)分析技術(shù),判定二進(jìn)制可執(zhí)行程序Crash 所屬漏洞類型的問題,通過結(jié)合動態(tài)污點(diǎn)分析方法,修改污點(diǎn)傳播規(guī)則,添加多種指令類型、寄存器和關(guān)鍵函數(shù)傳播約束和檢測方法,通過對常見緩沖區(qū)溢出漏洞崩潰觸發(fā)特征編寫觸發(fā)規(guī)則,在污點(diǎn)檢測階段提出面向漏洞類型的污點(diǎn)檢查點(diǎn)設(shè)置技術(shù),旨在解決自動化判定Crash的所屬漏洞類型的問題。

      2 關(guān)鍵技術(shù)

      2.1 二進(jìn)制代碼翻譯

      二進(jìn)制代碼翻譯(Binary Translation)[10]是將二進(jìn)制可執(zhí)行程序翻譯成另外一種指令集形式,二進(jìn)制代碼翻譯是安全領(lǐng)域研究的熱點(diǎn)問題,廣泛應(yīng)用于代碼移植、代碼優(yōu)化、模擬器、虛擬化等方面。二進(jìn)制代碼翻譯有兩種方法,分別是基于直接指令和基于中間語言,直接指令翻譯如圖1 所示:Source instruction 表示源ISA,它被二進(jìn)制翻譯器翻譯為目標(biāo)Target instruction。翻譯過程中可以進(jìn)行各種處理,如代碼優(yōu)化和profiling等?;谥苯又噶畹亩M(jìn)制代碼翻譯能夠有效處理給定的源和目標(biāo)指令,適合小型的二進(jìn)制可執(zhí)行程序,當(dāng)程序較大或需要一致性較高的翻譯器時,該方法會顯得極其復(fù)雜。

      圖1 直接指令翻譯流程

      基于中間語言的方法將二進(jìn)制可執(zhí)行程序翻譯成中間語言[11](Intermediate Representation,IR),IR是一種通用的表示形式,和平臺無關(guān)。圖2是采用中間語言的二進(jìn)制程序翻譯流程,只需要將二進(jìn)制可執(zhí)行程序翻譯成對應(yīng)的IR,而后通過不同架構(gòu)轉(zhuǎn)換規(guī)則進(jìn)行解讀和匹配,IR適用于大型程序的分析和指令轉(zhuǎn)換,對一些規(guī)模較小的二進(jìn)制程序則顯得效率低下[12]。例如,以下代碼是add eax,ebx指令的Vex表示:

      圖2 中間語言二進(jìn)制代碼翻譯流程

      2.2 動態(tài)污點(diǎn)分析和動態(tài)二進(jìn)制插樁

      動態(tài)污點(diǎn)分析將非信任來源數(shù)據(jù)標(biāo)記為污點(diǎn),通過污點(diǎn)標(biāo)記、污點(diǎn)傳播、檢測及策略匹配等階段來準(zhǔn)確獲取程序的執(zhí)行過程[13]。動態(tài)污點(diǎn)傳播一般采用虛擬執(zhí)行或動態(tài)二進(jìn)制插樁方式對污點(diǎn)數(shù)據(jù)進(jìn)行記錄和跟蹤。動態(tài)二進(jìn)制插樁指的是在程序運(yùn)行的過程中插入自定義代碼,監(jiān)控程序運(yùn)行狀態(tài),獲取程序運(yùn)行時狀態(tài)信息,從而對程序進(jìn)行分析的過程。Intel 公司開發(fā)的Pin插樁工具是最近幾年比較流行的插樁框架,Pin的基本思路是JIT 編譯并插入插樁代碼,同時進(jìn)行優(yōu)化處理以取得較高效率[14]。Pin 由幾部分組成:虛擬機(jī)VM、Code Cache(指令緩存)、插樁API,內(nèi)部架構(gòu)如圖3所示。

      VM包括JIT編譯器、Emulator和Dispatcher。JIT編譯插樁目標(biāo)程序代碼,由Dispatcher執(zhí)行。被編譯/插樁的機(jī)器指令放入指令緩存,以便后來執(zhí)行的代碼無需編譯就可直接執(zhí)行。Emulator模擬無法由JIT編譯的機(jī)器代碼,通常用于處理系統(tǒng)調(diào)用。選擇Pin 作為插樁開發(fā)框架主要有以下優(yōu)勢[15]。

      圖3 Pin插樁平臺系統(tǒng)架構(gòu)

      (1)普適性的插樁機(jī)制:使用動態(tài)二進(jìn)制插樁,不需要源代碼和重編譯。而論文所針對的目標(biāo)程序正好是沒有開放源代碼的二進(jìn)制可執(zhí)行程序/軟件,采用Pin是非常有效。

      (2)簡單容易的自定制,其自身包含了一套豐富的API編程接口,使得開發(fā)人員可以在現(xiàn)有Pintool的基礎(chǔ)上進(jìn)行改進(jìn)或者創(chuàng)建新的具有特定功能的Pintool。

      (3)多平臺的支持:支持x86、x86-64、Itanium、Xscale的體系架構(gòu)以及支持Linux、Windows、MacOS操作系統(tǒng)。

      (4)健壯性和穩(wěn)定性,能夠?qū)Χ喾N商業(yè)級的軟件進(jìn)行插樁,包括數(shù)據(jù)庫、瀏覽器等;能夠?qū)Χ嗑€程程序進(jìn)行插樁。

      (5)高效性:提供對插樁代碼的編譯優(yōu)化。

      Pin提供判斷操作數(shù)類型的API為:

      INS_OperandIsMemory(ins,1) // ins是指令,

      INS_OperandIsReg(ins,1)// 1 表示源操作數(shù),0 表示目的操作數(shù)

      插樁指令的核心函數(shù)原型如下:

      INS_InsertCall(ins,

      IPOINT_BEFORE,

      analysis_function,

      … //多個參數(shù)

      IARG_INT

      第一個參數(shù)是指令,第二個參數(shù)是插樁時刻,IPOINT_BEFORE是指令執(zhí)行前插樁,IPOINT_AFTER是指令執(zhí)行后插樁,第三個參數(shù)是用戶插樁分析例程,省略號表示多個參數(shù)(直到IARG_END 結(jié)束),這些參數(shù)都是分析例程的實(shí)參。

      3 系統(tǒng)設(shè)計實(shí)現(xiàn)

      3.1 標(biāo)記污點(diǎn)源

      污點(diǎn)分析的首要任務(wù)是識別污點(diǎn)源,將不可信輸入標(biāo)記為污點(diǎn)。二進(jìn)制可執(zhí)行程序Fuzz 出的Crash 本身就是一種二進(jìn)制形式的輸入文件,這里認(rèn)為Crash 就是污點(diǎn)源。為標(biāo)注污點(diǎn)源需截獲相關(guān)函數(shù),它有若干種方法實(shí)現(xiàn):(1)驅(qū)動程序,這種方法最徹底但編寫難度較大且不穩(wěn)定;(2)通過API截獲工具如Detours實(shí)現(xiàn)。這兩種方法的共同缺點(diǎn)在于需要與動態(tài)插樁工具交互,而Pin目前不支持與外部程序的IPC。動態(tài)插樁工具Pin提供了系統(tǒng)調(diào)用插樁,通過Pin 提供的API 可以方便獲取參數(shù)和返回值等信息,這里采用MANGO[16]插樁socket、recv、open、read 等系統(tǒng)調(diào)用標(biāo)記污點(diǎn)屬性,然后在執(zhí)行類似GET/PUT或LOAD/STORE之類的指令時對污點(diǎn)的傳播和刪除情況進(jìn)行污點(diǎn)標(biāo)記。污點(diǎn)標(biāo)記的過程如下。

      第一步:平臺捕獲sys_read 系統(tǒng)調(diào)用。通過Pin 可以初始化回調(diào)函數(shù)在系統(tǒng)調(diào)用出現(xiàn)前后添加自定義代碼進(jìn)行動態(tài)插樁獲取運(yùn)行時信息,采用的污點(diǎn)跟蹤技術(shù)粒度為字節(jié),接受外部輸入數(shù)據(jù)首先到達(dá)緩沖區(qū),對長度為buffLen 的讀入數(shù)據(jù)進(jìn)行污點(diǎn)標(biāo)注,污點(diǎn)表初始化偽代碼如下所示:

      TaintNOdeTable(buffer,buffLen)

      fori← 0 to buffLen?1 do

      //將地址 buffer+i插入到 taint_table 表中,taint_table為Hash表

      call taint_table_mem_insert(taint_table,buffer+i)

      //地址buffer+i的污點(diǎn)標(biāo)簽為

      taint_table_mem_add_tag(taint_table,buffer+i,taint_count,i+1)

      taint_count←taint_count+1

      第二步:獲取這部分內(nèi)存區(qū)域的相鄰后續(xù)參數(shù)。當(dāng)出現(xiàn)系統(tǒng)調(diào)用時,通過調(diào)用LEVEL_PINCLIENT::PIN_AddSyscallEntryFunction函數(shù)來檢查該塊內(nèi)存區(qū)域是否可讀,如果可讀則將后續(xù)參數(shù)保存,將該內(nèi)存區(qū)域添加到定義好的污染字節(jié)列表中,輸出相關(guān)執(zhí)行結(jié)果。

      第三步:當(dāng)出現(xiàn)類似LOAD 和STORE 指令時調(diào)用處理程序。為了在受污染的內(nèi)存區(qū)域中獲取LOAD/STORE所有指令,為每條指令添加一個主處理程序:

      typedef VOID(*LEVEL_PINCLIENT::

      INS_INSTRUMENT_CALLBACK)(INS ins,VOID *v);VOID LEVEL_PINCLIENT::

      INS_AddInstrumentFunction

      (INS_INSTRUMENT_CALLBACK fun,VOID * val);

      污點(diǎn)引入通過監(jiān)控 ReadFile()、RecvFrom()、Getchar()等污點(diǎn)輸入函數(shù)實(shí)現(xiàn),然后在調(diào)用函數(shù)時傳遞指令地址、反匯編代碼、內(nèi)存可讀區(qū)域的地址等信息[17],對STORE 類型的指令操作類似。內(nèi)存地址污點(diǎn)污點(diǎn)鏈表標(biāo)記如圖4所示。

      Taint_tag即為污點(diǎn)。比如標(biāo)記第一個緩沖區(qū)的第三個字節(jié),生成一個污點(diǎn)對象,對應(yīng)的count 為1,taint_tag為3,該字節(jié)所在的內(nèi)存地址經(jīng)運(yùn)過算對應(yīng)Memory_address_0的第二個偏移字節(jié),就將生成的污點(diǎn)對象插入Memory_address_0對應(yīng)Taint_1鏈表中。對接受到緩沖區(qū)的每個字節(jié)進(jìn)行標(biāo)記,以上就是污點(diǎn)標(biāo)記初始化的過程。

      3.2 動態(tài)污點(diǎn)跟蹤

      圖4 污點(diǎn)鏈表結(jié)構(gòu)

      污點(diǎn)跟蹤本質(zhì)上是對信息流的追蹤,動態(tài)污點(diǎn)跟蹤階段主要考慮污點(diǎn)的添加和刪除,調(diào)整污點(diǎn)傳播策略以避免出現(xiàn)污染過度和污染缺失現(xiàn)象[18]。例如,當(dāng)LOAD和STORE的對象是污點(diǎn)數(shù)據(jù)時,進(jìn)行污點(diǎn)標(biāo)記,當(dāng)STORE的目標(biāo)是常量時,由于無法控制,需要進(jìn)行污點(diǎn)清除。這里將對特定地址進(jìn)行標(biāo)記而不是將某一整塊內(nèi)存標(biāo)記為污點(diǎn)屬性[19],使用std::listaddrestaintted污染池保存污染地址,考慮到寄存器中的污點(diǎn)信息傳播,這里使用std::listregtaintted污染池記錄所有能被用戶控制的寄存器。動態(tài)污點(diǎn)傳播過程如圖5所示。

      設(shè)計污點(diǎn)傳播算法偽代碼如下所示:

      procedure TaintNodeinit(INS ins,void*t)

      switch typeof(ins)//指令傳播

      case:MOV|CMOVcc|R*L|R*R|XCHG|STOS|LEA//數(shù)據(jù)移動類指令

      e1=getSrcOperand(ins);e2=getDstOperand(ins);Taint(e1->e2)

      case:ADD*,MUL*,SUB*,AND*XOR//運(yùn)算類指令

      e1=getSrcOperand(ins);e2=getDstOperand(ins);bitset*s=Union(e1,e2);

      case:CMP|CMPS*//比較類指令

      e1=LeftOperand(ci);e2=RightOperand(ci);bitset*s=Union(e1,e2);……

      end procedure

      procedure Taintpropagation(INS ins,void*t)

      if(typeof(e1)==MEM(Reg)&&Mem(Reg)TaintMap[e1]!=Mem(Reg)TaintMap.end())

      //根據(jù)指令語義和關(guān)鍵函數(shù)的規(guī)則進(jìn)行污點(diǎn)傳播

      TaintNode *insertnode(ins_taint,reg_taint)

      end if

      else if(typeof(e1)==bitset)Mem(Reg)TaintMap[e2]=bitset_copy(e1)

      end else if

      elseif(Mem(Reg)TaintMap[e1]!=Mem(Reg)TaintMap.end())bitset_free(Mem(Reg)TaintMap[e1])

      //對如XOR等指令及一些函數(shù)進(jìn)行污點(diǎn)清除

      TaintNode *deletenode(ins_taint,reg_taint)

      end if

      end procedure

      TaintNodeUpdate(INS ins,void*t)

      //更新污點(diǎn)表(影子內(nèi)存與寄存器的污點(diǎn)狀態(tài))

      污點(diǎn)傳播需要建立污點(diǎn)源到污點(diǎn)操作數(shù)之間的傳播規(guī)則,具體如表1 所示,這里對x86_64 架構(gòu)下污點(diǎn)相關(guān)指令和函數(shù)進(jìn)行總結(jié)歸類[20],指令級污點(diǎn)傳播主要有以下幾種方式:

      (1)數(shù)據(jù)移動類指令,例如mov、movb、movsz、movxz等,污點(diǎn)傳播規(guī)則時間將源操作數(shù)的污點(diǎn)標(biāo)記賦給目的操作數(shù)。

      (2)運(yùn)算類指令,典型指令有add、sub、and、xor、shr、lhr 等,傳播規(guī)則是將源和目的操作數(shù)的污點(diǎn)標(biāo)記賦給目的操作數(shù)。

      圖5 動態(tài)污點(diǎn)傳播過程

      表1 污點(diǎn)傳播指令及關(guān)鍵函數(shù)的規(guī)則說明

      (3)單操作數(shù)指令,典型指令有not、push、pop 等,not傳播規(guī)則是清除操作數(shù)污點(diǎn)標(biāo)記,pop傳播規(guī)則是將rsp內(nèi)存污點(diǎn)信息賦給操作數(shù)。

      (4)復(fù)雜尋址,典型指令如mov(base_reg,index_reg,immd),reg,傳播規(guī)則是在內(nèi)存訪問時將內(nèi)存地址以及基址寄存器和變址寄存器的污點(diǎn)標(biāo)記賦給目的操作數(shù)。

      對于敏感關(guān)鍵函數(shù),主要考慮strlen(char* str)、int strcmp(char*p1,char*p2)、strcat(char *p1,char*p2)、int atoi(char *str)、memset(void *m,charc,int len)、void* malloc(int len)、free(p)等函數(shù)的傳播策略。

      污點(diǎn)表更新模塊主要是污點(diǎn)鏈表中污點(diǎn)的添加和刪除操作,通過對程序進(jìn)行指令級插樁,分析指令執(zhí)行過程的污點(diǎn)傳播情況,需要對每條指令做出如下判斷:該指令是否是內(nèi)存/寄存器操作指令?該指令是否引起污點(diǎn)傳播?污染表數(shù)據(jù)結(jié)構(gòu)包含IN 和OUT 兩個污染表,分別為同一個block的前后污染信息集合,根據(jù)設(shè)定的傳播策略對滿足條件的指令進(jìn)行taint_tag 添加和刪除,最后完成對污點(diǎn)表的合并更新。

      3.3 檢查點(diǎn)(SINK點(diǎn))設(shè)置

      污點(diǎn)檢查點(diǎn)是進(jìn)行漏洞檢測和Crash類型識別的關(guān)鍵環(huán)節(jié),污點(diǎn)檢測主要針對已經(jīng)被標(biāo)記為污染源的數(shù)據(jù)進(jìn)行檢測,記錄在程序中的使用情況并通過監(jiān)控污點(diǎn)數(shù)據(jù)傳播信息來實(shí)現(xiàn)漏洞類型判斷等操作[21]。為完成以上目標(biāo),需要獲取二進(jìn)制可執(zhí)行程序中的單個模塊中的所有關(guān)鍵函數(shù)和對應(yīng)的關(guān)鍵字節(jié),為此設(shè)計三個識別模塊:關(guān)鍵函數(shù)識別模塊、函數(shù)調(diào)用跟蹤模塊、關(guān)鍵字節(jié)識別模塊。關(guān)鍵函數(shù)識別模塊需要找到插樁程序中哪些函數(shù)使用了污點(diǎn)數(shù)據(jù),哪些關(guān)鍵函數(shù)是漏洞觸發(fā)的高危函數(shù),例如printf函數(shù)族、atoi函數(shù)等;函數(shù)調(diào)用跟蹤模塊分析插樁程序內(nèi)部的函數(shù)調(diào)用關(guān)系,明確正在執(zhí)行的指令屬于該模塊內(nèi)的哪個函數(shù);關(guān)鍵字節(jié)識別模塊分析插樁程序指令所使用的關(guān)鍵字節(jié)。當(dāng)某條指令使用了污染數(shù)據(jù),通過關(guān)鍵字節(jié)識別模塊可獲得相關(guān)的關(guān)鍵字節(jié),通過函數(shù)調(diào)用跟蹤模塊可獲得該指令屬于哪個關(guān)鍵函數(shù),將上面的關(guān)鍵字節(jié)歸類為關(guān)鍵函數(shù)。這樣隨著程序的運(yùn)行,即可收集到每個關(guān)鍵函數(shù)的關(guān)鍵字節(jié)。本文主要對棧溢出、堆溢出、格式化字符串進(jìn)行漏洞檢測,具體檢查點(diǎn)設(shè)置方法如下:

      對二進(jìn)制可執(zhí)行程序進(jìn)行插樁,讀入Crash 后運(yùn)行至程序崩潰,收集崩潰點(diǎn)上下文信息。對棧溢出類型的漏洞進(jìn)行檢查點(diǎn)設(shè)置通過檢測在LOAD/STORE指令中對原先棧幀的訪問過程,和當(dāng)前棧幀進(jìn)行對比,如果當(dāng)前棧幀指針高于原棧幀位置,則EIP 可以由用戶控制,該Crash是棧溢出類型的。堆溢出漏洞成因是一塊堆內(nèi)存被釋放了之后又被使用,又被使用指的是:指針存在(懸垂指針被引用),這個引用的結(jié)果是不可預(yù)測的,因?yàn)椴恢罆l(fā)生什么。對于該種類型漏洞在污點(diǎn)檢查點(diǎn)選擇捕獲malloc和free函數(shù)的所有調(diào)用,當(dāng)malloc發(fā)生時在列表中保存這些信息,比如基地址、內(nèi)存大小和分配狀態(tài)(是占用還是空閑),當(dāng)執(zhí)行LOAD或STORE指令時,檢查該地址是否在列表中,而后檢查其標(biāo)志,如果該標(biāo)志是free且在LOAD或STORE中有權(quán)限訪問,那就認(rèn)為是堆溢出漏洞。格式化字符串漏洞兩大危害是內(nèi)存泄漏和內(nèi)存寫數(shù)據(jù),主要借助于%s、%c、%d、%p、%x、%n等格式符,格式化字符串的檢查點(diǎn)比較簡單,主要是針對printf函數(shù)族進(jìn)行污點(diǎn)檢查,驗(yàn)證是否符合函數(shù)規(guī)范,且現(xiàn)在的編譯器都增加了對格式化符檢測機(jī)制,因此該漏洞的實(shí)驗(yàn)驗(yàn)證階段主要通過CTF 試題和收集的一些存在格式化字符串漏洞的小程序?qū)υ拖到y(tǒng)進(jìn)行測試。

      4 實(shí)驗(yàn)分析

      本文主要基于Pin插樁平臺開發(fā)出對二進(jìn)制可執(zhí)行程序進(jìn)行漏洞檢測,并對二進(jìn)制可執(zhí)行程序Fuzz 出的Crash 進(jìn)行分類的工具。實(shí)驗(yàn)對象是存在棧溢出、格式化字符串、堆溢出等緩沖區(qū)溢出漏洞的二進(jìn)制可執(zhí)行程序,Crash 是由對應(yīng)的二進(jìn)制可執(zhí)行程序進(jìn)行模糊測試得到或從一些測試集中獲取,實(shí)驗(yàn)環(huán)境如表2所示。

      表2 實(shí)驗(yàn)環(huán)境

      綜合以上幾節(jié),提出Crash 分類框架如圖6 所示。二進(jìn)制可執(zhí)行程序通過Pin進(jìn)行插樁,讀入Crash文件,在污點(diǎn)標(biāo)記階段對Crash 進(jìn)行污點(diǎn)標(biāo)注,污點(diǎn)信息分別標(biāo)注于內(nèi)存區(qū)域、寄存器指令、關(guān)鍵函數(shù)等,在污點(diǎn)傳播階段進(jìn)行依據(jù)設(shè)定策略進(jìn)行污點(diǎn)跟蹤,主要涉及到重復(fù)污點(diǎn)傳播合并和無關(guān)污點(diǎn)指令刪除,在污點(diǎn)檢查點(diǎn)收集崩潰點(diǎn)上下文信息,根據(jù)不同類型設(shè)置污點(diǎn)檢查點(diǎn)。

      圖6 系統(tǒng)執(zhí)行架構(gòu)圖

      類型判定階段主要采用模式匹配方法,通過分析對污點(diǎn)信息收集模塊獲取的LOAD/STORE 指令,寄存器狀態(tài)、內(nèi)存地址特征,匹配棧溢出、格式化串、堆溢出漏洞崩潰特征。

      輸出如下:輸出崩潰點(diǎn)上下文的污點(diǎn)傳播情況、崩潰點(diǎn)指令操作和對應(yīng)的寄存器內(nèi)容、棧溢出崩潰點(diǎn)地址、Crash所屬漏洞類型等。

      4195584:mov dword ptr[rbp-0x8],0x90909090(rsp:7ffc53538080)(rbp:7ffc53538080)

      4195591:mov dword ptr [rbp-0xc],0x91919191(rsp:7ffc53538080)(rbp:7ffc53538080)

      [Write Mem B] 400507:mov dword ptr [rbp-0xc],0x91919191

      counterWrite:1

      4195598:mov dword ptr [rbp-0x4],0x0(rsp:7ffc53538080)(rbp:7ffc53538080)

      [Write Mem B] 400523:mov byte ptr [rax],0x45

      counterWrite:1

      [Write Mem B] 400523:mov byte ptr [rax],0x45

      counterWrite:2

      [Write Mem B] 400523:mov byte ptr [rax],0x45

      counterWrite:3

      [Write Mem B] 400523:mov byte ptr [rax],0x45

      counterWrite:4

      [Write Mem B] 400523:mov byte ptr [rax],0x45

      400523:mov byte ptr [rax],0x45 -- Stack overflow in 7ffc53538078

      counterWrite:0

      如圖7所示,結(jié)合IDA進(jìn)行具體分析驗(yàn)證該工具的有效性,打開IDA,將位置定位到0x400523,F(xiàn)5 翻譯成偽代碼進(jìn)行分析,_int64 foo()函數(shù)兩個變量v1、v2 在*((_BYTE *)&v1+(signed int)i)=69存在棧溢出漏洞。

      圖7 IDA驗(yàn)證棧溢出函數(shù)

      為了證明該原型系統(tǒng)在Crash類型驗(yàn)證方面的實(shí)用性,實(shí)驗(yàn)驗(yàn)證階段選取10個CTF二進(jìn)制可執(zhí)行程序和5個二進(jìn)制CVE漏洞進(jìn)行測試,如表3所示。CTF二進(jìn)制程序?qū)?yīng)的Crash由AFL進(jìn)行fuzzing得出,CTF賽題有棧溢出、堆溢出及格式化字符串3 種且較為簡單,對這些Crash 逐個進(jìn)行手動調(diào)試并結(jié)合BitBlaze 工具確認(rèn)Crash 所屬漏洞類型,留待與原型系統(tǒng)測試結(jié)果進(jìn)行比對。二進(jìn)制CVE 漏洞程序中,有存在格式化字符串漏洞的Wu-ftpd 2.6.0、Sudo.10,棧溢出漏洞的Libtiff 3.9.2和SWS 0.1.7,堆溢出漏洞的Libproxy 0.3.1,這些漏洞及對應(yīng)的Crash 由NVD 漏洞庫[22]、吾愛漏洞[23]等網(wǎng)站獲取,Crash類型已經(jīng)標(biāo)注。

      表3 實(shí)驗(yàn)驗(yàn)證分析歸納

      以CVE-2000-0537 為例,該漏洞是在wu-ftpd 2.6.0及其更早版本中存在的漏洞,是一個典型的格式化字符漏洞,可將用戶輸入的數(shù)據(jù)作為格式化字符串傳送給vsprintf()函數(shù)。通過原型系統(tǒng)驗(yàn)證,可以確定漏洞觸發(fā)地址、棧幀布局、寄存器信息以及Crash 所屬類型等信息。實(shí)驗(yàn)結(jié)果表明原型系統(tǒng)可以有效甄別Crash所屬漏洞類型。原型系統(tǒng)準(zhǔn)確識別出的Crash所屬類型數(shù)目占Crash樣本標(biāo)注所屬類型數(shù)的比例近似于71%。

      由于Crash 數(shù)量大,與漏洞有直接或間接關(guān)系的Crash比例很小,對于由系統(tǒng)無效訪問,空指針訪問等與漏洞無關(guān)的無利用價值Crash,這里不進(jìn)行考慮。通過對以上程序進(jìn)行Crash 類性判定,與原Crash 樣本中標(biāo)注的Crash 所屬漏洞類性進(jìn)行對比,可以計算原型系統(tǒng)判定的準(zhǔn)確率。該原型系統(tǒng)的誤報主要是因?yàn)槁┒从|發(fā)規(guī)則模塊編寫不夠完善,雖然同種漏洞的原理是一樣的,但是觸發(fā)形式多種多樣,如何合理編寫觸發(fā)特征以減少誤報,是下一步實(shí)驗(yàn)的重點(diǎn)研究之一。

      5 結(jié)束語

      Crash 分析是漏洞挖掘利用的關(guān)鍵環(huán)節(jié),本文主要研究Linux 系統(tǒng)下針對二進(jìn)制可執(zhí)行程序Fuzz 出的Crash 進(jìn)行分類的問題,提出一種基于污點(diǎn)分析的分類方法,在Pin 插樁平臺上設(shè)計了對二進(jìn)制可執(zhí)行程序進(jìn)行漏洞檢測和Crash 分類的工具。實(shí)驗(yàn)證明,該工具能夠有效地識別出二進(jìn)制可執(zhí)行程序存在的漏洞類型,并判斷出Crash和其中的某種漏洞相關(guān)。但該工具存在三個主要問題:一是無法有效對存在復(fù)合漏洞的二進(jìn)制可執(zhí)行程序進(jìn)行分析;二是檢測漏洞的類型不夠完善,由于漏洞觸發(fā)規(guī)則模塊編寫不夠全面,對堆的一些其他漏洞(Fastbin、協(xié)議、邏輯漏洞等)無法進(jìn)行檢測;三是污點(diǎn)傳播過程中對指令類型的傳播規(guī)則設(shè)定不夠全面,由于指令集異常龐大,沒有考慮到一些特殊指令,例如xchg、cdq、rtdsc 等,這在一定程度上增加了誤報率。下一步,將針對以上問題對該工具進(jìn)行改進(jìn),在污點(diǎn)傳播階段增加指令覆蓋面,重點(diǎn)研究如何完善漏洞觸發(fā)規(guī)則,提高匹配效率。

      猜你喜歡
      插樁污點(diǎn)二進(jìn)制
      砂土中樁靴插樁對臨近筒型基礎(chǔ)的影響研究
      基于代碼重寫的動態(tài)污點(diǎn)分析
      用二進(jìn)制解一道高中數(shù)學(xué)聯(lián)賽數(shù)論題
      基于TXL的源代碼插樁技術(shù)研究
      有趣的進(jìn)度
      二進(jìn)制在競賽題中的應(yīng)用
      基于性能分析的自適應(yīng)插樁框架
      使用Lightroom污點(diǎn)去除工具清理照片中的瑕疵
      我國“污點(diǎn)證人”刑事責(zé)任豁免制度的構(gòu)建
      基于順序塊的嵌入式白盒測試插樁技術(shù)研究
      上高县| 成都市| 金山区| 历史| 原平市| 南江县| 华安县| 临夏市| 曲沃县| 沧州市| 田林县| 和静县| 东丰县| 乐平市| 上林县| 曲周县| 修水县| 巴塘县| 聂拉木县| 九台市| 梁山县| 耒阳市| 绿春县| 乌什县| 正定县| 繁峙县| 张北县| 成安县| 咸阳市| 福鼎市| 高唐县| 兖州市| 荆州市| 临泉县| 靖江市| 磴口县| 遵义市| 华安县| 新津县| 任丘市| 茶陵县|