日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1.什么是系統(tǒng)調(diào)用

系統(tǒng)調(diào)用是從用戶模式過渡到內(nèi)核模式的標準方式。它們是現(xiàn)代版的軟件中斷,速度更快。

系統(tǒng)調(diào)用接口極其復雜,但由于大部分內(nèi)容與我們的工作無關(guān),我只想做一個較高層次的總結(jié)。在大多數(shù)情況下,你并不需要深入了解它是如何工作的,就可以使用這些技術(shù),但了解一下還是有幫助的。

在 windows 中,內(nèi)核有一張允許從用戶模式調(diào)用的函數(shù)表。這些函數(shù)有時被稱為系統(tǒng)服務、本地函數(shù)或 Nt 函數(shù)。它們是以 Nt 或 Zw 開頭的函數(shù),位于 ntoskrnl.exe 中。系統(tǒng)服務表稱為系統(tǒng)服務描述符表,簡稱 SSDT。

要從用戶模式調(diào)用系統(tǒng)服務,必須執(zhí)行系統(tǒng)調(diào)用,通過 syscall 指令完成。應用程序?qū)⑾到y(tǒng)服務 ID 保存在 eax 寄存器中,以此告訴內(nèi)核要調(diào)用哪個系統(tǒng)服務。系統(tǒng)服務 ID(通常稱為系統(tǒng)服務號、系統(tǒng)調(diào)用號或簡稱 SSN)是該函數(shù)在 SSDT 中的索引項。因此,將 eax 設置為 0 將調(diào)用 SSDT 中的第一個函數(shù),1 將調(diào)用第二個函數(shù),2 將調(diào)用第三個函數(shù),依此類推...

查詢結(jié)果如下:entry = nt!KiServiceTable+(SSN * 4)。

syscall 指令會使 CPU 切換到內(nèi)核模式并調(diào)用系統(tǒng)調(diào)用處理程序,該程序會從 eax 寄存器中獲取 SSN 并調(diào)用相應的 SSDT 函數(shù)。

假設一個應用程序調(diào)用 kernel32.dll 中的 OpenProcess() 函數(shù)來打開一個進程的句柄。

繞過用戶模式EDR Hook原理及思路圖片

正如你所看到的,該函數(shù)的真正作用是調(diào)用位于 ntdll.dll 中的 NtOpenProcess()。現(xiàn)在,讓我們來看看 NtOpenProcess() 的邏輯。

繞過用戶模式EDR Hook原理及思路圖片

在 NtOpenProcess() 中,幾乎沒有任何代碼。這是因為與所有以 Nt 或 Zw 開頭的函數(shù)一樣,NtOpenProcess() 實際上位于內(nèi)核中。這些函數(shù)的 ntdll(用戶模式)版本只是執(zhí)行系統(tǒng)調(diào)用來調(diào)用其內(nèi)核模式對應函數(shù),這就是為什么它們經(jīng)常被稱為系統(tǒng)調(diào)用存根。

在我們的例子中,NtOpenProcess 的 SSN 是 0x26,但這個數(shù)字會隨著 Windows 版本的變化而變化,所以不要指望它對你來說也是一樣的。從簡化的高層視圖來看,調(diào)用流程大致如下:

繞過用戶模式EDR Hook原理及思路圖片

下面是關(guān)于 x86 系統(tǒng)調(diào)用流程的更詳細概述:

繞過用戶模式EDR Hook原理及思路圖片

注意:在用戶模式下,函數(shù)的 Nt 和 Zw 版本完全相同。在內(nèi)核模式下,Zw 函數(shù)的運行路徑略有不同。這是因為 Nt 函數(shù)是為從用戶模式調(diào)用而設計的,因此要對函數(shù)參數(shù)進行更廣泛的驗證。

2.EDR和用戶模式鉤子

自 2005 年微軟推出內(nèi)核補丁保護(又稱 PatchGuard)以來,許多對內(nèi)核的修改現(xiàn)在都被阻止了。以前,安全產(chǎn)品通過掛鉤 SSDT 從內(nèi)核內(nèi)部監(jiān)控用戶模式調(diào)用。由于所有 Nt/Zw 功能都是在內(nèi)核中實現(xiàn)的,因此所有用戶模式調(diào)用都必須通過 SSDT,并因此受到 SSDT 掛鉤的影響。補丁防護使 SSDT 鉤子成為禁區(qū),因此許多 EDR 鉤子轉(zhuǎn)向掛鉤 ntdll。

繞過用戶模式EDR Hook原理及思路圖片

由于 SSDT 存在于內(nèi)核中,因此用戶模式應用程序無法在不加載內(nèi)核驅(qū)動程序的情況下干擾這些鉤子。現(xiàn)在,鉤子被放置在用戶模式下,與應用程序并存。

那么,用戶模式鉤子是什么樣的呢?

繞過用戶模式EDR Hook原理及思路圖片

要掛接 ntdll.dll 中的函數(shù),大多數(shù) EDR 只需用 jmp 指令覆蓋函數(shù)代碼的前 5 個字節(jié)。jmp 指令會將代碼執(zhí)行重定向到 EDR 自身 DLL(會自動加載到每個進程中)中的某些代碼。CPU 被重定向到 EDR 的 DLL 后,EDR 可以通過檢查函數(shù)參數(shù)和返回地址來執(zhí)行安全檢查。一旦 EDR 完成檢查,它就可以通過執(zhí)行覆蓋指令恢復 ntdll 調(diào)用,然后跳轉(zhuǎn)到鉤子(jmp 指令)之后的 ntdll 位置。

繞過用戶模式EDR Hook原理及思路圖片

在上例中,NtWriteFile 被掛鉤。綠色指令是 NtWriteFile 的原始指令。NtWriteFile 的前 3 條指令已被 EDR 的鉤子(將執(zhí)行重定向到 edr.dll 中名為 NtWriteFile 的函數(shù)的 jmp)覆蓋。每當 EDR 想要調(diào)用真正的 NtWriteFile 時,它會執(zhí)行 3 條被覆蓋的指令,然后跳轉(zhuǎn)到掛鉤函數(shù)的第 4 條指令,完成系統(tǒng)調(diào)用。

雖然不同廠商的 EDR 掛鉤可能略有不同,但原理仍然相同,而且都有一個共同的弱點:它們都位于用戶模式下。由于鉤子和 EDR 的 DLL 都必須放在每個進程的地址空間內(nèi),因此惡意進程可以篡改它們。

3.繞過EDR鉤子

繞過 EDR 鉤子的方法有很多,我只介紹主要的幾種。

卸載EDR鉤子

由于掛鉤的 ntdll 位于我們自己進程的內(nèi)存中,因此我們可以使用 VirtualProtect() 使內(nèi)存可寫,然后用原始函數(shù)代碼覆蓋 EDR 的 jmp 指令。為了替換鉤子,我們當然需要知道原來的匯編指令是什么。最常見的方法是從磁盤讀取 ntdll.dll 文件,然后將內(nèi)存版本與磁盤版本進行比較。前提是 EDR 不會檢測或阻止從磁盤手動讀取 ntdll.dll。

這種方法的主要缺點是,EDR 可以定期檢查 ntdll 的內(nèi)存,查看其鉤子是否已被刪除。如果 EDR 檢測到其鉤子已被移除,它可能會將鉤子寫回,更有甚者會終止進程并觸發(fā)檢測事件。雖然鉤子可能需要放在用戶模式下,但檢查鉤子可以在內(nèi)核模式下進行,因此我們也沒有什么辦法來防止這種情況發(fā)生。

手動映射DLL

與其從磁盤中讀取 ntdll 的純凈拷貝來解鎖原始 ntdll,我們還不如直接將純凈拷貝加載到進程內(nèi)存中,然后使用它來代替原始 ntdll。由于 LoadLibrary() 和 LdrLoadDll() 等函數(shù)不允許系統(tǒng)兩次加載同一個 DLL,所以我們必須手動加載。手動映射 DLL 的代碼可能會很繁雜,而且容易出錯或被檢測到。

DLL 通常也會調(diào)用其他 DLL,因此我們要么只能使用手動加載的 ntdll 中的函數(shù),要么為我們需要的每個 DLL 加載第二個副本,并修補它們,使其只能使用其他手動加載的 DLL,這可能會變得非常混亂。如果殺毒軟件在進行內(nèi)存掃描時,發(fā)現(xiàn)每個 DLL 都有多個副本加載到內(nèi)存中,那么也很有可能被發(fā)現(xiàn)。

直接系統(tǒng)調(diào)用

正如前面討論的那樣,用戶模式下的Nt/Zw函數(shù)實際上除了執(zhí)行系統(tǒng)調(diào)用之外并不執(zhí)行其他任何操作。因此,我們實際上不需要映射整個新的ntdll副本來執(zhí)行一些系統(tǒng)調(diào)用。相反,我們可以直接將系統(tǒng)調(diào)用邏輯實現(xiàn)到我們自己的代碼中。我們只需將要調(diào)用的函數(shù)的SSN(函數(shù)號)移動到eax寄存器中,然后執(zhí)行syscall指令。

__asm {
  mov r10, rcx
  mov eax, 0x123
  syscall
  ret
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

不幸的是,由于EDR的鉤子通常會覆蓋設置eax寄存器的指令,我們不能簡單地從被掛鉤的函數(shù)中提取它。但是...有一些方法我們可以找出它是什么。

從ntdll讀取一個干凈的拷貝

你可能已經(jīng)對這個想法感到厭倦了,但我們可以從磁盤上讀取一個干凈的ntdll副本,然后從中提取SSN。由于SSN始終被放入eax寄存器,我們只需掃描我們想要調(diào)用的函數(shù)以找到"mov eax, imm32"指令即可。但是,如果我們想要一種不僅僅是從磁盤讀取ntdll的變體呢?別擔心!

根據(jù)函數(shù)順序計算系統(tǒng)調(diào)用號

系統(tǒng)調(diào)用ID是索引,因此是順序的。如果我們想要調(diào)用的函數(shù)的SSN是0x18,那么直接在它之前的可能是0x17,直接在它之后的可能是0x19。由于EDR并不掛鉤每個Nt函數(shù),我們可以簡單地從最近的未被掛鉤的函數(shù)中獲取SSN,然后通過添加或減去在它和我們目標函數(shù)之間有多少個函數(shù)來計算我們想要的函數(shù)的SSN。

繞過用戶模式EDR Hook原理及思路圖片

這種方法確實有一個缺陷:我們無法百分之百地保證系統(tǒng)調(diào)用號將永遠保持連續(xù),或者DLL不會跳過一些。

硬編碼

最簡單的方法就是直接硬編碼系統(tǒng)調(diào)用號。雖然它們在不同版本之間會有所改變,但在過去它們的變化并不是很大。檢測操作系統(tǒng)版本并加載正確的SSN集并不是太難的工作。事實上,j00ru友好地發(fā)布了每個Windows版本的每個系統(tǒng)調(diào)用號的列表。這種方法唯一的缺點是,如果系統(tǒng)調(diào)用號發(fā)生變化,代碼可能在新的Windows版本上無法自動運行。

直接系統(tǒng)調(diào)用的問題

在過去的十多年里,直接系統(tǒng)調(diào)用一直是繞過用戶模式鉤子的首選方法。實際上,我自己在2012年初次嘗試了這種方法。不幸的是,為了防止這種繞過方式,已經(jīng)進行了很多工作。最常見的檢測方法是讓EDR的內(nèi)核模式驅(qū)動程序檢查調(diào)用堆棧。

盡管EDR不能再在內(nèi)核中掛鉤很多地方,但它可以利用操作系統(tǒng)提供的監(jiān)視功能,比如:

  • ETW事件
  • 內(nèi)核回調(diào)
  • 過濾驅(qū)動程序

如果我們執(zhí)行手動系統(tǒng)調(diào)用,而在調(diào)用的內(nèi)核函數(shù)經(jīng)過以上任何一種情況時,EDR可以利用機會檢查我們線程的調(diào)用堆棧。通過展開調(diào)用堆棧并檢查返回地址,EDR可以看到導致此系統(tǒng)調(diào)用的整個函數(shù)調(diào)用鏈。

如果我們執(zhí)行對kernel32!VirtualAlloc()的正常調(diào)用,調(diào)用堆棧可能如下所示:

繞過用戶模式EDR Hook原理及思路圖片

在這種情況下,對VirtualAlloc()的調(diào)用是由ManualSyscall!mAIn+0x53啟動的。按照調(diào)用的順序,調(diào)用堆棧的相關(guān)部分如下:

  • ManualSyscall!main+0x53
  • KERNELBASE!VirtualAlloc+0x48
  • ntdll!NtAllocateVirtualMemory+0x14
  • nt!KiSystemServiceCopyEnd+0x25

這告訴我們(或者EDR)可執(zhí)行文件(ManualSyscall.exe)調(diào)用了VirtualAlloc(),這個函數(shù)調(diào)用了NtAllocateVirtualMemory(),然后執(zhí)行了一個系統(tǒng)調(diào)用以切換到內(nèi)核模式。

現(xiàn)在讓我們看看進行直接系統(tǒng)調(diào)用時的調(diào)用堆棧:

繞過用戶模式EDR Hook原理及思路圖片

調(diào)用堆棧的相關(guān)部分按順序如下:

  • ManualSyscall!direct_syscall+0xa
  • nt!KiSystemServiceCopyEnd+0x25

在這里,很明顯內(nèi)核轉(zhuǎn)換是由ManualSyscall.exe內(nèi)部的代碼觸發(fā)的,而不是ntdll。但是,這有什么問題嗎?

嗯,在像linux這樣的系統(tǒng)上,應用程序直接發(fā)起系統(tǒng)調(diào)用是完全正常的。但請記住我提到過Windows版本之間系統(tǒng)調(diào)用號會發(fā)生變化嗎?結(jié)果,編寫依賴于直接系統(tǒng)調(diào)用的Windows軟件是非常不切實際的。由于ntdll已經(jīng)為您實現(xiàn)了每個系統(tǒng)調(diào)用,幾乎沒有理由進行手動系統(tǒng)調(diào)用。除非你正在編寫繞過EDR鉤子的惡意軟件。你是在寫用于繞過EDR鉤子的惡意軟件嗎?

由于直接系統(tǒng)調(diào)用是惡意活動的強有力指標,更復雜的EDR系統(tǒng)將記錄源自于ntdll之外的系統(tǒng)調(diào)用的檢測情況。說實話,你仍然可以在很多時候逃脫檢測,但這有什么樂趣呢?

4.間接系統(tǒng)調(diào)用

 

大多數(shù)EDR在Nt函數(shù)的開頭寫入它們的鉤子,覆蓋SSN但保留系統(tǒng)調(diào)用指令不變。這使我們能夠利用ntdll已經(jīng)提供的系統(tǒng)調(diào)用指令,而不是引入我們自己的。我們只需自己設置r10和eax寄存器,然后跳轉(zhuǎn)到被掛鉤的ntdll函數(shù)內(nèi)的系統(tǒng)調(diào)用指令(位于EDR鉤子之后)。

繞過用戶模式EDR Hook原理及思路圖片

注意:我們并不嚴格需要test或jnz指令,它們只是為了向后兼容。一些古老的CPU不支持syscall指令,而是使用int 0x2e。test指令檢查系統(tǒng)調(diào)用是否啟用,如果沒有啟用,則回退到軟中斷。如果我們希望支持這些系統(tǒng),我們可以自己執(zhí)行檢查,然后根據(jù)需要跳轉(zhuǎn)到int 0x2e指令(也位于Nt函數(shù)內(nèi))。

就像直接系統(tǒng)調(diào)用一樣,我們?nèi)匀恍枰到y(tǒng)調(diào)用號放入eax寄存器,但我們可以使用在直接系統(tǒng)調(diào)用部分詳細介紹的所有相同技術(shù)。

通過這種方式設置系統(tǒng)調(diào)用將給我們一個類似以下的調(diào)用堆棧:

繞過用戶模式EDR Hook原理及思路圖片

正如你所看到的,調(diào)用堆棧現(xiàn)在看起來好像是來自ntdll!NtAllocateVirtualMemory()而不是我們的可執(zhí)行文件,因為從技術(shù)上講確實是這樣的。

我們可能會遇到的一個問題是,如果EDR鉤子或覆蓋了Nt調(diào)用中的syscall指令的部分。我從未見過這種情況發(fā)生,但理論上可能會發(fā)生。在這種情況下,我們可以跳轉(zhuǎn)到另一個未被掛鉤的Nt函數(shù)內(nèi)的syscall指令。這仍然可以繞過僅驗證調(diào)用名稱是否來自ntdll的EDR,但對于檢查內(nèi)核函數(shù)是否與來自ntdll的函數(shù)相匹配的這種檢查通常都會失敗。

更大的問題是,如果EDR檢查的不僅僅是第一個返回地址。不僅僅是系統(tǒng)調(diào)用的來源,還有執(zhí)行系統(tǒng)調(diào)用的函數(shù)是誰調(diào)用的。如果我們正在從位于動態(tài)分配內(nèi)存中的某個shellcode進行間接系統(tǒng)調(diào)用,那么EDR將會察覺到。來自于有效PE節(jié)(exe或DLL內(nèi)存)之外的調(diào)用是相當可疑的。

此外,由于函數(shù)被EDR掛鉤,EDR的鉤子預期會出現(xiàn)在調(diào)用堆棧中。實際上,我并不確定哪些EDR,如果有的話,會檢查這一點。但是,正如你在這里看到的,從調(diào)用堆棧中很明顯我們繞過了EDR的鉤子。

繞過用戶模式EDR Hook原理及思路圖片

理想情況下,我們希望偽造的不僅僅是系統(tǒng)調(diào)用的返回地址。對此的一個有趣解決方案是調(diào)用堆棧欺騙,我可能會在另一篇文章中詳細介紹。使用調(diào)用堆棧欺騙,可以偽造整個調(diào)用堆棧,但要保持調(diào)用堆棧穩(wěn)定不崩潰可能會遇到一些挑戰(zhàn)。

分享到:
標簽:EDR Hook
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定