
Generates x86, x64, or AMD64+x86 position-independent shellcode that loads .NET Assemblies, PE files, and other Windows payloads from memory and runs them with parameters

Current version: v1.1
Donut is a position-independent code that enables in-memory execution of VBScript, JScript, EXE, DLL files and dotNET assemblies. A module created by Donut can either be staged from a HTTP server or embedded directly in the loader itself. The module is optionally encrypted using the Chaskey block cipher and a 128-bit randomly generated key. After the file is loaded and executed in memory, the original reference is erased to deter memory scanners. The generator and loader support the following features:
There are dynamic and static libraries for both Linux and Windows that can be integrated into your own projects. There's also a python module which you can read more about in Building and using the Python extension.
Donut contains individual loaders for each supported file type. For dotNET EXE/DLL assemblies, Donut uses the Unmanaged CLR Hosting API to load the Common Language Runtime. Once the CLR is loaded into the host process, a new Application Domain is created to allow for running Assemblies in disposable AppDomains. When the AppDomain is ready, the dotNET Assembly is loaded via the AppDomain.Load_3 method. Finally, the Entry Point for EXEs or public method for DLLs specified by the user is invoked with any additional parameters. Refer to MSDN for documentation on the Unmanaged CLR Hosting API. For a standalone example of a CLR Host, refer to code here.
VBScript and JScript files are executed using the IActiveScript interface. There's also minimal support for some of the methods provided by the Windows Script Host (wscript/cscript). For a standalone example, refer to code here. For a more detailed description, read: In-Memory Execution of JavaScript, VBScript, JScript and XSL
Unmanaged or native EXE/DLL files are executed using a custom PE loader with support for Delayed Imports, TLS and patching the command line. Only files with relocation information are supported. Read In-Memory Execution of DLL for more information.
The loader can disable AMSI and WLDP to help evade detection of malicious files executed in-memory. For more information, read How Red Teams Bypass AMSI and WLDP for .NET Dynamic Code. It also supports decompression of files in memory using aPLib or the RtlDecompressBuffer API. Read Data Compression for more information.
As of v1.0, ETW is also bypassed. Like with AMSI/WLDP, this a modular system that allows you to swap out the default bypass with your own. The default bypass is derived from research by XPN. Read Hiding your .NET - ETW for more information.
By default, the loader will overwrite the PE headers of unmanaged PEs (from the base address to `IMAGE_OPTIONAL_HEADER.SizeOfHeaders`). If no decoy module is used (module overloading), then the PE headers will be zeroed. If a decoy module is used, the PE headers of the decoy module will be used to overwrite those of the payload module. This is to deter detection by comparing the PE headers of modules in memory with the file backing them on disk. The user may request that all PE headers be preserved in their original state. This is helpful for scenarios when the payload module needs to access its PE headers, such as when looking up embedded PE resources.
For a detailed walkthrough using the generator and how Donut affects tradecraft, read Donut - Injecting .NET Assemblies as Shellcode. For more information about the loader, read Loading .NET Assemblies From Memory.
Those who wish to know more about the internals should refer to Developer notes.
There are two types of build. If you want to debug Donut, please refer to documentation here. If not, continue reading for the release build.
From a Windows command prompt or Linux terminal, clone the repository.
git clone http://github.com/thewover/donut.git