?

基于動態分析的控制流劫持攻擊檢測

2021-06-03 02:22吳小王劉露平
關鍵詞:漏洞指令應用程序

吳小王, 方 勇, 賈 鵬, 劉露平, 王 炎

(1.四川大學網絡空間安全學院, 成都 610065; 2. 四川大學電子信息學院, 成都 610065)

1 引 言

網絡空間是一個沒有硝煙的戰場,從1988年的Morris蠕蟲病毒到2017年的WannaCry勒索病毒足以可見網絡空間安全的嚴峻態勢. 據CNVD[1]最新的收錄漏洞類型統計,應用程序漏洞占比高達58.45%,并且漏洞數量在逐年增多. 越來越多的高級持續性威脅(Advanced Persistent Threat,APT)利用應用程序漏洞執行破壞行為[2],對網絡空間安全造成巨大的威脅. 盡管各大軟件廠商在不斷改進和完善軟件開發質量管理,但軟件漏洞問題仍無法徹底消除.

應用程序漏洞的利用方式多種多樣,而控制流劫持攻擊是最常見的一種. 控制流劫持攻擊允許攻擊者破壞程序的控制數據,通常將執行流重定向到攻擊者自己的注入代碼. 通過執行惡意代碼能夠完全控制程序和系統,造成極大的危害. 目前的操作系統中部署了地址空間布局隨機化(Address Space Layout Randomization,ASLR)、數據執行保護(Data Execution Protection,DEP)、結構化異常處理安全校驗(Safe Structured Exception Handling,SafeSEH)等安全機制,一定程度上緩解了控制流劫持攻擊對軟件和系統的危害. 但是,因為系統環境的多樣性,攻擊者仍然能夠找到繞過這些安全機制的方法. 因此,如何快速高效地發現攻擊威脅并及時采取應對措施一直是學術界的研究熱點.

由Abadi等人于2005年提出的控制流完整性CFI(Control Flow Integrity)是目前防御控制流劫持攻擊的主要技術[3]. CFI的核心思想是獲取程序間接轉移指令的合法目標并以此構造應用程序的控制流圖CFG(Control Flow Graph),強制程序在CFG的范圍內運行,能有效地防御控制流劫持攻擊. 自提出CFI后,對控制流劫持攻擊防御的研究有很大的推進作用,出現了如binCFI[4]、CCFI[5]為代表的粗粒度的CFI;為提高CFI防御能力的上下文敏感的CFI[6],基于數據約束的vCFI[7],操作系統內核層面的KCoFI[8],專門針對ROP攻擊的ROPecker[9],隨機選擇特定跳轉進行驗證的RCFI[10].

動態污點分析[11]是檢測漏洞攻擊的另一種主要技術,該技術跟蹤程序數據在程序內部的傳播,分析程序數據是否處于敏感位置,如常見的函數返回地址,從而檢測控制流劫持攻擊.

CFI策略雖然能夠有效的防御控制流劫持攻擊,但是難以在實際環境中部署. 其主要原因有兩點:(1) 是CFG的構造困難,完整的CFG構造需要依賴程序源碼,對于復雜的程序而言更是難以實現. 雖然沒有源碼情況下通過逆向分析等技術也可以構建CFG,但是對于采用了加殼[12]、混淆[13]等保護技術的二進制程序,構建CFG難以實現;(2) 是需要檢查程序中的每一個間接控制轉移,細粒度的檢測會引起非常大的開銷. 此外,動態污點分析技術在實際檢測中存在過污染、欠污染等問題,所以效率較低且精度不高.

針對上述問題,本文提出了一種新的檢測控制流劫持攻擊的方法:在分析控制流劫持攻擊原理的基礎上,總結了控制流劫持攻擊的行為特征,然后基于二進制插樁技術,通過動態分析應用程序的異常行為,來檢測控制流劫持攻擊. 與現有的動態污點分析技術和基于CFI策略的控制流劫持攻擊檢測方法相比,本文方法解決了二進制文件分析需要依賴源碼[14]和修改二進制文件的問題,因此具有良好的移植性;另外,所有的檢測分析僅在程序運行時進行,不需要靜態分析和預處理的過程,具備良好的性能開銷,可以方便地部署于各種系統環境中.

2 控制流劫持攻擊研究

文獻[15]總結了控制流劫持攻擊的基本流程(如圖1). 一個完整的控制流劫持攻擊包含以下5個步驟:構造特定的攻擊載體;觸發并利用應用程序中的內存破壞漏洞;劫持程序的控制流;繞過DEP、ASLR等安全防護;最后控制程序執行流轉向惡意代碼,實現漏洞攻擊.

圖1 控制流劫持攻擊流程圖

2.2 控制流劫持攻擊行為

2.2.1 執行惡意代碼 執行惡意代碼主要有代碼注入和代碼復用兩種方式. 注入的惡意代碼被稱為shellcode,一般布置到應用程序的??臻g或者堆空間中. ??臻g用于存放函數參數的值、局部變量的值和函數調用保存的棧幀信息,正常程序不會從??臻g解析指令執行,常見的程序漏洞如緩沖區溢出[16],則會將惡意代碼布置到??臻g中執行. 堆是程序運行過程中動態使用的內存空間,用于存放數據,也用于存放動態生成的指令,因此應用程序存在堆空間執行指令的情況.

攻擊者除了利用自己構造的惡意代碼,還有可能利用程序本身的代碼,這種利用方式稱為代碼重用技術[17],如常見的ROP[18]攻擊. ROP攻擊利用程序本身的指令片段,這些指令片段稱為gadget,每個gadget由ret指令結尾. 通過ret指令將分散的指令片段連接起來,能實現與shellcode相同的功能.

ASLR技術增加了ROP構造的難度,DEP技術使得注入代碼無法執行. 因此,代碼注入通常與代碼復用相結合,首先使用ROP關閉shellcode所在空間的數據執行保護,然后執行shellcode.

2.2.2 造成程序異常 實際的漏洞利用過程中構造的攻擊載體一般是針對特定的操作系統和目標程序,而現實中的系統環境多種多樣,因此有不少的漏洞攻擊會因為環境不同致使應用程序出現內存訪問異常甚至崩潰的情況.

漏洞攻擊除了被動觸發程序異常,還有主動觸發異常并利用異常的情況. 當應用程序出現異常,Windows系統下會調用結構化異常處理函數SEH(Structured Exception Handling,)進行異常處理. 圖2展示了SEH鏈表結構.

圖2 SEH鏈表Fig.2 SEH chain

SEH鏈表的每一個節點都包含Next和Handler兩個成員,其中,Handler指向具體的異常處理函數,Next則指向SEH鏈表的下一個節點,最后一個節點的Next指向為0xFFFFFFFF. 攻擊者可以通過觸發異常,然后覆蓋SEH鏈表中的Handler地址來劫持程序的控制流,間接地破壞了SEH鏈表的完整性.

本文通過對控制流劫持攻擊原理的研究,分析了在不同的漏洞利用攻擊情況下程序的異常行為. 提出了基于動態分析的控制流劫持攻擊檢測方法,該方法通過動態獲取程序運行時信息,針對不同的程序異常行為分別制定檢測方法.

程序的內存空間可以分為模塊地址空間(程序加載的庫文件和可執行程序本身)、??臻g和堆空間等3個區域. ??臻g主要存放的是函數調用時相關的信息,并不會存放代碼指令,所以若發現函數執行流程跳轉到棧中,則說明存在漏洞攻擊行為. 如果不位于??臻g,則可能是位于堆空間中的惡意代碼執行. 由于堆空間可能執行應用程序動態生成的代碼,因此不能直接判定為惡意代碼執行. 但是,通常在執行堆空間惡意代碼前會使用ROP關閉shellcode所在內存空間的數據執行保護,因此,可以通過檢測ROP防御部分堆空間惡意代碼執行.圖3為棧執行檢測流程圖.

圖3 棧執行檢測

程序執行過程中,獲取當前線程的??臻g范圍,如果執行的指令地址位于??臻g范圍內,則檢測到棧執行.

3.2 ROP攻擊檢測

文獻[18]表明程序本身的一些指令片段可以構造出圖靈完備的代碼. ROP攻擊可以利用程序本身的代碼片段執行一些函數的功能,比如調用VirtualProtect函數改變內存空間的可執行權限,使得堆空間中的惡意代碼能夠執行,或者僅僅使用ROP就完成攻擊行為. 圖4為ROP攻擊檢測流程圖.

圖4 ROP攻擊檢測Fig.4 ROP attack detection

ROP攻擊利用的指令片段稱為gadget,這些gadget一般由幾條指令組成,并以ret指令結尾,ret指令讓這些gadget聯系在一起,通過順序執行這些gadget完成一系列功能操作.

程序正常執行過程中函數調用與函數返回一般是匹配的,雖然存在特殊的ret指令與call指令不匹配的現象,但不會出現連續的ret與call不匹配的現象. 文獻[18]表明實際的ROP攻擊至少有17個連續的gadget,而程序正常執行最多可能存在10個連續的gadget. 因此,為了減少誤報率和漏報率,節省時間開銷,將連續出現的11個ret異常識別為ROP攻擊,具體檢測流程如圖5,通過構造影子棧,檢測到11個連續的異常ret指令,判定為ROP攻擊.

KiUserExceptionDispatcher函數是Windows系統下異常處理的起點,該函數有兩個參數PEXCEPTION_RECORD和PCONTEXT,分別記錄程序異常的具體信息和程序發生異常時的上下文信息. 控制流劫持攻擊中程序異常分為以下兩種情況:(1) 是攻擊失敗造成的異常;(2) 是攻擊者為了利用SEH造成的異常. 對于第二種異常情況,程序在進行異常處理前SEH鏈表中的handler已經被惡意數據覆蓋,導致SEH鏈表不再具備圖2所示的完整結構. 因此,需要在KiUserExceptionDispatcher函數被調用時獲得程序異常的具體信息和檢查SEH鏈表的完整性. SEH異常檢測流程如圖5.

圖5 SEH異常檢測Fig.5 SEH detection

當捕獲到KiUserExceptionDispatcher函數調用時,首先判斷異常類型. 如果異常類型是“訪問無效地址”,直接判定為SEH異常; 如果不是,則接著檢查SEH鏈表的完整性,如果SEH鏈表不完整則判定為SEH異常,否則,繼續應用程序的異常監控.

在程序動態運行過程中,通過以上3種方法同時對程序的異常行為進行監控,結合程序運行時信息,實現對控制流劫持攻擊的檢測以及控制流劫持攻擊地址定位和類型判斷.

Pin[19]是Intel公司開發的用于動態分析的二進制程序插樁工具,通過及時編譯技術在程序原有代碼中插入分析代碼,從而獲取程序動態運行時信息.相較于基于QEMU虛擬環境的動態分析方式,基于Pin的動態分析技術能夠直接在應用環境中使用. 因此基于Pin工具設計了控制流劫持攻擊檢測系統CFHADS(Control Flow Hijacking Attack Detection System). 圖6為CFHADS系統架構圖.

圖6 CFHADS系統架構Fig.6 System structure of CFHADS

CFHADS主要由動態信息提取模塊和動態檢測2個模塊組成. 其中,動態信息提取模塊獲取應用程序運行時信息以供動態檢測模塊實時分析. 使用Pin工具提供的INS_AddInstrumentFunction函數進行指令插樁、PIN_AddThreadStartFunction函數進行線程插樁、RTN_InsertCall函數進行敏感API插樁. 指令插樁主要分析call指令和ret指令,并結合線程插樁,獲取應用程序線程創建的相關信息為每個線程構建影子棧;敏感API插樁主要分析程序異常處理過程中用到的函數并獲取其參數. 此外,使用Pin工具提供豐富的API,可為動態檢測模塊提供應用程序運行過程中任意時刻的上下文信息,如寄存器狀態、內存數據等.

動態檢測模塊根據動態信息提取模塊提供的程序運行時信息,實現本文提出的控制流劫持攻擊檢測方法中的棧執行檢測方法、ROP攻擊檢測方法和SEH異常檢測方法.我們通過對3種程序異常行為的檢測實現對控制流劫持類攻擊的檢測,檢測到攻擊的同時,保存漏洞攻擊的細節,用于后續分析.

5 實驗與分析

我們將用真實的漏洞攻擊樣本對系統的功能和性能進行測試,表1為具體的實驗環境配置.

表1 實驗環境配置

5.1 功能測試

為了驗證CFHADS系統的攻擊檢測效果,選取了26個真實漏洞進行功能測試,這些漏洞都是針對的常用應用程序,包括Microsoft office word、Microsoft office Excel、Foxit Reader、Adobe Acrobat Reader、IE等.漏洞利用樣本主要來源于exploit-db和metasploit. 具體檢測結果如表2所示.

CVE-2012-0158是針對常用軟件Microsoft office word 2007的經典漏洞,該漏洞利用未開啟ASLR保護的msxml5.dll中跳板指令繞過DEP的安全防護,使用了經典的跳板指令jmp esp控制應用程序在??臻g中執行惡意代碼. 該漏洞實際的利用方式是ret-to-libc,CFHADS雖然沒有檢查ret-to-libc中最開始的異常跳轉,但是準確檢測到控制流劫持攻擊的后續異常行為. 表2的檢測結果顯示,EDB-ID-42918和CVE-2018-7886采用了與CVE-2012-0158相似的利用方式.

表2 真實漏洞攻擊檢測結果

CVE-2010-1797是針對PDF閱讀器Foxit Reader的漏洞攻擊,該漏洞采取了SEH利用的方式,CFHADS的檢測結果為內存訪問異常+SEH利用+棧執行,完整地記錄了漏洞攻擊從觸發內存漏洞、劫持程序控制流到最后執行惡意代碼的異常行為. 由于實際的系統環境與漏洞攻擊的目標環境存在差異,因此檢測結果中以內存訪問異常居多. CVE-2010-2883采用的攻擊方式為Heap Spray+ROP,但是漏洞利用失敗,應用程序icucnv36.dll偏移0x2a715處訪問無效內存地址0x0導致崩潰退出. 雖然漏洞攻擊沒有完整實施后續的ROP攻擊,CFHADS仍準確地檢測到漏洞攻擊造成的程序異常.

實驗結果表明,CFHADS能檢測到控制流劫持攻擊各個環節的程序異常行為,雖然主要是檢測棧執行、ROP攻擊和SEH利用,但是也間接防御了ret-to-libc、堆利用等攻擊,除了檢測到完整的控制流劫持攻擊,也能檢測到漏洞利用失敗的控制流劫持攻擊.

5.2 性能測試

通過Windows系統下常用的5個應用程序測試CFHADS對應用程序的性能影響,圖7展示了應用程序在沒有附加Pin、附加原生Pin、附加CFHADS情況下的應用程序內存占用情況.

從圖7可以看出,Pin的運行開銷約為原程序的3倍,而CFHADS的運行開銷約為Pin的1.2倍. 因此,相對于基于虛擬機實現的漏洞攻擊檢測系統,CFHADS可以直接部署到實際應用環境中進行實時的控制流劫持攻擊檢測.

圖7 原程序、Pin、CFHADS內存占用對比

本文提出了一種基于動態分析的控制流劫持攻擊檢測方法,在不依賴靜態分析或者預處理的情況下檢測應用程序運行時的控制流劫持攻擊. 通過對控制流劫持攻擊整個流程的詳細分析,總結控制流劫持攻擊在實際環境中造成的各種異常及行為特征,識別應用程序中的異常行為并判定為攻擊. 本文基于動態分析技術實現了控制流劫持攻擊檢測系統,通過真實的漏洞攻擊檢測實驗,表明該系統能夠準確檢測到控制流劫持攻擊,良好的運行開銷使得該系統能夠部署到實際的應用環境中.

考慮到簡單的ret-to-libc難以達到攻擊目的、JOP在實際漏洞利用中實現困難以及直接將控制流轉移到堆空間中執行惡意代碼實現復雜等情況,本文提出的方法沒有針對以上攻擊方式的具體檢測手段,因此在遇見這些情況時可能會產生漏報. 另外,由于Linux系統與Windows系統的一些運行機制及處理機制的不同,本文提出的方法目前只適用于Windows系統. 后續研究計劃中將進一步優化檢測方法,提高控制流劫持攻擊檢測的全面性.

猜你喜歡
漏洞指令應用程序
漏洞
《單一形狀固定循環指令G90車外圓仿真》教案設計
刪除Win10中自帶的應用程序
新機研制中總裝裝配指令策劃研究
關于ARM+FPGA組建PLC高速指令控制器的研究
谷歌禁止加密貨幣應用程序
偵探推理游戲(二)
漏洞在哪兒
三星電子將開設應用程序下載商店
太空第一人
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合