红蓝对抗之如何利用Shellcode来躲避安全检测
寫在前面的話
? ? ? ? 對于紅隊安全研究團隊來說,一次成功的滲透測試必須是不被目標系統發現的,隨著現代終端檢測和響應(EDR)產品日趨成熟,紅隊也必須隨之每日俱進。在這篇文章中,我們將跟大家介紹FireEye Mandiant紅隊研究人員如何通過構造特殊Payload來繞過現代EDR產品,并獲取到目標系統的完整命令控制訪問權。
? ? ? ? Shellcode注入或Shellcode執行往往是我們在目標系統上實現Payload執行的最優方法,那么什么是Shellcode呢?Michael Sikorski將其定義為:“用于描述任何自包含可執行代碼的術語”。大多數商業滲透測試框架,比如說Empire、Cobalt Strike或MetaSploit,它們都內置有Shellcode生成器,而這種Shellcode生成器一般都是二進制或十六進制格式,具體需要取決于用戶是將其以原始輸出還是應用源碼的形式生成的。
我們為什么要使用Shellcode呢?
? ? ? ? 對于Payload類型來說,Shellcode所能帶來的靈活性非常高。Shellcode可以使用多種編程語言來編寫,而且這些語言可以跟很多類型的Payload進行整合。除此之外,Shellcode的這種靈活性允許我們根據需求并在任何環境下構建定制的Payload。因為Shellcode可以直接以Payload作為載體運行,或注入到任何正在運行的進程中,我們就可以使用多種技術來躲避EDR產品的檢測了,這些技術包括Shellcode代碼混淆、編碼以及加密等等,這樣可以大幅增加商業EDR產品的檢測難度。
在這篇文章中,我們將介紹如何使用下列三種方法來隱蔽地運行Shellcode:
1、CreateThread
2、CreateRemoteThread
3、QueueUserAPC
? ? ? ? 其中的每一項技術都會對應一個Windows API函數,而這些函數將會負責分配Shellcode的執行線程,并最終實現Shellcode的運行。CreateThread主要負責Shellcode的執行,CreateRemoteThread和QueueUserAPC主要負責Shellcode的注入。
CreateThread工作流程
1、為當前進程分配內存;
2、將Shellcode拷貝到分配的內存中;
3、修改新分配內存的保護機制,以允許Shellcode在內存空間中運行;
4、使用已分配內存段的基地址創建線程;
5、等待返回線程句柄;
CreateRemoteThread
1、獲取目標注入進程的進程ID;
2、打開目標進程;
3、在目標內存中分配可執行內存;
4、將Shellcode寫入到已分配內存中;
5、使用已分配內存段的起始地址在遠程進程中創建一個線程;
QueueUserAPC
1、獲取目標注入進程的進程ID;
2、打開目標進程;
3、為目標進程分配內存;
4、向已分配內存中寫入Shellcode;
5、修改新分配內存的保護機制,以允許Shellcode在內存空間中運行;
6、使用已分配內存段的起始地址在遠程進程中創建一個線程;
7、當線程進入“預警”狀態時,將線程提交至執行隊列;
8、將線程恢復至“預警”狀態;
命令執行
大家先停一下,我們整理一下:
1、惡意代碼就是我們的Shellcode – stage 0或stage 1代碼是真正執行惡意操作的代碼。
2、標準的“Shellcode運行程序”會通過注入或直接執行的方式來運行惡意代碼。
? ? ? ? 接下來,我們還需要一種執行已編譯代碼的方法,一般來說,我們可以通過可執行程序(exe)或動態鏈接庫(DLL)來實現,不過紅隊研究人員更愿意使用lolbins命令來執行。
信息整合
我們將開發一個Shellcode運行工具(DLL),它可以利用lolbins實現,并且可以在不需要更新代碼庫的情況下實現注入式或非注入式的Shellcode,以此來保證靈活性。完成之后,我們將得到一個名叫DueDlligence的C# Shellcode運行程序,源代碼可以點擊【這里】獲取。
DueDlligence項目可以快速地在之前提到的技術之間進行切換,我們只需要修改下圖中的全局變量值即可:
DueDLLigence DLL包含三個非托管的導出函數,這三個導出函數使用了Rasautou,Control,和Coregen這三個原生的Windows命令(本文所使用的Shellcode樣本只會彈出calc.exe):
?
打開源代碼之后,你會發現樣本使用了下列導出函數:
首先,我們要生成我們的Shellcode,下圖中,我們使用了Cobalt Strike來生成“rev_dns”監聽器的原始Shellcode。完成之后,我們需要在Linux中運行下列命令來生成base64編碼版本的Shellcode:
base64 -w0 payload.bin > [outputFileName]? ? ? ? 接下來,我們需要用base64編碼的我們自己的x86或x64 Payload替換第58行的base64編碼的Shellcode,上圖中我們生成了一個x86 Payload,有需要的話你可以修改“use x64 Payload”來生成一個x64 Payload。
? ? ? ? 此時,我們需要重新安裝DueDLLigence(Visual Studio項目)中的未托管導出庫,,因為有時當你使用不同的項目時,可能會導致DueDLLigence項目出現問題。你可以打開NuGet包管理終端,然后運行下列命令:
Install-Package UnmanagedExports -Version 1.2.7 command? ? ? ? 完成上述所有操作之后,需要構建源碼和DLL。Visual Studio Pro自帶的Dumpbin.exe可以幫助我們運行和測試生成的DLL,并查看導出函數:
? ? ? ? 我們可以使用其他的lolbin技術來擴展上圖中的導出函數列表,不過大家盡量把不需要使用的移除掉以減小Payload的體積。
Shellcode注入技術的現代檢測方法
? ? ? ? 盡管Shellcode可以幫助我們規避檢測,但還是有可能被檢測到的,下面我們來分析幾種進程注入技術。
? ? ? ? 在我們的Shellcode運行程序中,Shellcode注入技術(CreateRemoteThread和QueueUserAPC)會以掛起狀態生成一個進程,然后向目標進程中注入Shellcode。比如說,我們選擇explorer.exe來作為注入目標,我們的Payload將通過MSIExec來運行。之后會生成一個進程樹,cmd.exe將生成msiexec.exe,并最終生成explorer.exe。
? ? ? ? 在企業環境中,可以使用SIEM來收集遙測數據,以檢測cmd.exe -> msiexec.exe -> explorer.exe進程樹的執行情況。根據父-子進程的關系,防御端可以通過異常檢測來識別潛在的惡意軟件。
? ? ? ? API鉤子是EDR和反病毒產品常用的惡意軟件檢測技術,很多攻擊者會使用類似PsSetCreateProcessNotifyRoutine(Ex)和PsSetCreateThreadNotifyRoutine(Ex)這樣的內核程序來實現攻擊。當進程注入發生時,一個進程會修改另一個進程地址空間中的內存保護機制,通過檢測類似API的調用情況,隨著紅隊和惡意攻擊者繼續開發新的進程注入技術,網絡防御人員以及安全軟件需要繼續適應不斷變化的環境。監視諸如virtualAllocex、virtualProtectEx、createRemoteThread和ntQueueAPCThread之類的Windows API函數調用可以為識別潛在惡意軟件提供有價值的數據。除此之外,監視create process與create_suspended和create_hidden標志的使用可能有助于檢測攻擊者要注入的掛起或隱藏的進程。
總結
? ? ? ? 使用Shellcode作為紅隊研究過程中Payload感染的最后階段,不僅可以方便研究人員在各種各樣的目標環境中執行Payload,而且還可以實現安全產品的規避。DueDLLigence Shellcode運行程序是一個動態工具,它可以給紅隊研究人員提供一種“現成”的安全產品規避方法。
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的红蓝对抗之如何利用Shellcode来躲避安全检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql if语句
- 下一篇: python 标准库之 glob 介绍(