2018年10月31日 星期三

Hook Function (攔截函式)

在剛接觸駭客技術不久的初學者,很多都不太認識”Hook Function”到底是什麼東西 ? 這篇主要是說明什麼是Hook Function以及它的用途和歸納不同平台的作業系統有哪些使用的技巧。

一、Hook Function


Hook Function主要目的用於分析參數的運行狀態,以及改變參數的數值,例如在分析惡意程式時,它可能會判斷此時是否有使用Debugger在分析它,這時就可以Hook掉偵測Debugger的Function,讓它的回傳值都是當前無Debugger的狀態,這樣就可以簡單地繞過它的防護了。

a. 正常的Function運作流程


FunctionA是一個function,它會傳入1、2、3,這三個參數給functionB,然後functionB會回傳0資料給functionA,以此類推functionB和functionC。



b. 被Hook Function的流程


當functionB被Hook,就可以分析和控制傳入參數的數值,以及回傳值,因此可以將參數任意改成2、3、4給functionB,並將回傳值改成1給functionA,上述只是舉例,在實際環境可以依造需求而改變數值達到目的地。



二、Hook Function 實用技巧


a. 共通性作業系統平台


  • Inline Hook:這是在Hook Function最常用的手法,因為它可以在記憶體的任意位址插入跳轉程式(JMP),並控制執行流程,因此可以非常靈活的使用。

  • IDT (Interrupt Descriptor Table) Hook:當硬體(觸發滑鼠或鍵盤)或系統發生中斷,就會通過這個Table裡面定義的位址,分別處理不同的中斷,例如INT 1 是觸發硬體中斷點(Hardware Breakpoint),它就會參考IDT的第一個Table。大部分會用到IDT Hook,都是因為要鍵盤偵測(INT 0x93),因為在作業系統裡有分為,處理USB鍵盤的Function和PS鍵盤的Function,因此直接在低階的IDT,就可以簡單快速達到鍵盤偵測。

  • GDT (Global Descriptor Table):GDT是作業系統中的記憶體管理的機制,在GDT Hook是需要新增一個自己定義的GDT,並且修改要Hook的IDT Selector,使它進入到自己新增的GDT,由於GDT的base address已被修改,因此就可以神不知鬼不覺的讓IDT被Hook。

  • Hardware Breakpoint Hook:Hardware Breakpoint是透過CPU的暫存器(DR0 – DR3)來判斷是否要中斷這個位址,因此可以Hook掉處理Hardware Breakpoint的Function,並設定要Hook的Function的位址到DR0 – DR3中的其一,在執行到此Function,就會觸發Hardware Breakpoint中斷,這樣也可以達到Hook Function。

b. Windows 作業系統平台


  • IAT (Import Address Table) Hook:IAT是存放此程式使用到DLL (Dynamic-link library) Function的絕對位址,當程式要執行Function時,會參考IAT,因此我只要修改對應此Function的位址值,就可以成功的Hook。

  • EAT (Export Address Table) Hook:與IAT相反,EAT是提供給外部使用的function,因此也可以修改它,達到Hook Function的目的。

  • SSDT (System Service Dispatch Table) Hook:SSDT是存放核心層的系統Function (API - Application Programming Interface),因此只要簡單的替換裡面的位址,就可以很輕易的達到目的。

  • Sysenter Hook:在系統要從Ring 3去呼叫Ring 0的Function要透過INT 0x2e,不過這會影響系統的效能,因此在Windows 7後,大部分Function都使用Systenter,所以只要Hook Sysenter的IA32_SYSENTER_EIP (MSR - Model Specific Registers),就可以Hook全部的Function。

  • IRP (I/O Request Packet) Hook:IRP是處理I/O的請求封包,當應用層呼叫處理I/O的API (Application Programming Interface),底層的驅動就會透過IRP傳遞資料給其他要處理它的驅動,因此可以將自己的驅動程式插入到最先處理IRP的地方,這樣就可以第一時間監控這些資料,在Visual Studio本身就有提供這些方法(驅動過濾)來Hook IRP。


c. Linux 作業系統平台


  • sys_call_table Hook:這跟Windows的SSDT很像,都是存放系統Function (API - Application Programming Interface)的位址,因此替換裡面的位址值,就可以很輕易的Hook Function。

  • Netfilter Hook:Netfilter是Linux的內建機制,因此直接調用註冊(nf_register_hook)的API (Application Programming Interface)就可以很簡單的Hook網路封包 (iptable就使透過這個機制實現的)。

  • VFS (Virtual File System) Hook:Linux因為需要支援不同的檔案系統,因此應用層與核心層所使用的統一介面架構,因此只要處理檔案相關的,都會使用VFS的架構,這些架構下只要定義自己的open、write、read等等的Function,然而可以替換這些Function Pointer,就可以輕鬆的達到此目的。

  • GOT (Global Offset Table) Hook:GOT 是存放使用.so (Shared Object)內部Function的位址,不過在未執行這個Function時,此時GOT是PLT (Procedure Linkage Table)的位址,需要透過它(_dl_runtime_resolve)來尋找Function在.so的位址,並且重新寫到GOT裡面,因此我們可以替換GOT來達到此目的。

通過了解不同的手法來Hook Function,並提升自己的技術,在實戰時,可能會因為某些防護偵測,因而需要使用其他技巧來繞過它,此時就必須靈活的使用這些手法。