Skip to content

KriyosArcane/pumpbin

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

107 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PumpBin

PumpBin is an implant generation platform for red teams. Write a shellcode loader, package it as a .b1n, stamp shellcode into it, and apply post-build transforms in one command.

Not a C2. Not a shellcode generator. Sits between them.

Quick start

You have a compiled loader binary with PumpBin markers:

$ pumpbin-cli stamp loader.exe payload.bin
PB  loader.exe            win/exe  [*] reading loader
PB  loader.exe            win/exe  [*] injecting shellcode (460 B)
PB  loader.exe            win/exe  [+] wrote stamp.exe

You are writing the loader from scratch:

$ pumpbin-cli new-loader myloader --platform windows --pack
PB  myloader              win/exe  [*] cargo build (release)
PB  myloader              win/exe  [+] packed -> myloader/myloader.b1n
wrote myloader/myloader.b1n
Scaffolded and packed: myloader/myloader.b1n

$ pumpbin-cli generate -p myloader -s payload.bin
PB  myloader.b1n          win/exe  [*] loading plugin
PB  myloader.b1n          win/exe  [*] injecting shellcode (460 B)
PB  myloader.b1n          win/exe  [+] wrote myloader.exe

Commands

$ pumpbin-cli --help

Usage: pumpbin-cli [OPTIONS] <COMMAND>

Commands:
  stamp        Pack a loader binary and stamp shellcode in one step
  generate     Stamp shellcode into an existing .b1n
  batch        Stamp shellcode from a directory of .bin files
  new-loader   Scaffold a new Rust loader crate
  pack         Build a loader crate and produce a .b1n
  create-b1n   Pack a pre-built binary into a .b1n
  inspect      Inspect a .b1n or check a loader binary for markers
  build        Build from a pumpbin.toml profile
  module       List and test modules
  check        Pre-flight YARA scan
  convert      Reformat shellcode bytes
  list-donors  Find PEs with embedded Authenticode signatures
  completions  Print shell completion script

stamp

$ pumpbin-cli stamp --help

Usage: pumpbin-cli stamp [OPTIONS] <LOADER> <SHELLCODE>

Arguments:
  <LOADER>     Compiled loader binary (PE, ELF, or Mach-O)
  <SHELLCODE>  Raw shellcode file (.bin)

Options:
  -o, --output <OUTPUT>       Output path  [default: stamp.<ext>]
      --post <ID[:K=V,K=V]>  Post-build module, repeat to chain
      --save-b1n <PATH>       Save the intermediate .b1n for later reuse

Advanced:
      --platform <PLATFORM>  Override auto-detected platform
  -t, --type <TYPE>          Binary type (exe, lib)  [default: exe]
      --marker <MARKER>      Shellcode placeholder  [default: $$SHELLCODE$$]

With post-build transforms:

$ pumpbin-cli stamp loader.exe payload.bin \
    --post cert-graft:donor=/path/to/signed.exe \
    --post byte-patch:patches=4831d2:4833d2 \
    --output implant.exe
PB  loader.exe            win/exe  [*] reading loader
PB  loader.exe            win/exe  [*] injecting shellcode (460 B) + cert-graft, byte-patch
PB  loader.exe            win/exe  [+] wrote implant.exe

Save the .b1n for reuse with generate:

$ pumpbin-cli stamp loader.exe payload.bin --save-b1n loader.b1n
PB  loader.exe            win/exe  [*] reading loader
PB  loader.exe            win/exe  [*] saved .b1n -> loader.b1n
PB  loader.exe            win/exe  [*] injecting shellcode (460 B)
PB  loader.exe            win/exe  [+] wrote stamp.exe

generate

$ pumpbin-cli generate -h

Usage: pumpbin-cli generate [OPTIONS] --plugin <PLUGIN> --shellcode <SHELLCODE>

Options:
  -p, --plugin <PLUGIN>        .b1n plugin pack or crate directory
  -s, --shellcode <SHELLCODE>  Shellcode file (.bin) or remote URL
  -o, --output <OUTPUT>        Output path  [default: <name>.<ext>]
      --post <ID[:K=V,K=V]>   Post-build module, repeat to chain
      --dry-run                Preview without writing

Advanced:
      --platform <PLATFORM>        Target platform (auto-detected from .b1n)
  -t, --type <TYPE>                Binary type (auto-detected from .b1n)
      --module-config <KEY=VALUE>  Override module config

Preview before generating:

$ pumpbin-cli generate -p myloader -s payload.bin --dry-run

DRY RUN: nothing will be written

  Plugin:       myloader (v0.1.0)
  Target:       Linux / Exe
  Output:       myloader.elf
  Shellcode:    payload.bin (460 B)
  Module chain: (none)

Post-build modules

Attach transforms with --post. Order matters. Two forms:

--post cert-graft
--post cert-graft:donor=/path/to/signed.exe
--post byte-patch:patches=4831d2:4833d2,mode=all
--post pe-version-info:from_donor=/path/to/signed.exe

List installed modules:

$ pumpbin-cli module list

encrypt:
  aes-gcm (built-in) - AES-256-GCM with random key/nonce per generation
  xor (built-in) - Single-byte XOR with random non-zero key
format_url:
  url-passthrough (built-in) - Embeds the operator URL verbatim
post_build:
  pe-version-info (built-in) - Patch VS_VERSION_INFO StringFileInfo entries in a PE
  byte-patch (built-in) - Apply in-place hex byte substitutions to the implant (equal-length pairs only)
  cert-graft (built-in) - Graft a donor PE's WIN_CERTIFICATE onto the implant (cert blob only; use external `trustmebro` for full clone)

Show args for a specific module:

$ pumpbin-cli module list --options --id byte-patch

post_build:
  byte-patch (built-in) - Apply in-place hex byte substitutions to the implant (equal-length pairs only)
    patches: string (required)
        Comma-separated <hex_from>:<hex_to> pairs; each pair must be equal length
    mode: string [default: all]
        `all` (replace every occurrence) or `first` (replace only first)

Drop-in modules go in ~/.config/pumpbin/modules/<id>/. A TOML manifest and an executable in any language. See MODULES.md.

inspect

Works on .b1n files and compiled loader binaries.

Check a loader for markers before stamping:

$ pumpbin-cli inspect myloader/target/release/myloader

file:      myloader/target/release/myloader (306480 bytes)
format:    linux

markers:
  shellcode    "$$SHELLCODE$$"   offset 0x4824
  size-holder  "$$99999$$"       offset 0x6B23

capacity:  4096 bytes (4 KiB)

verdict:   SUITABLE: ready for pumpbin-cli stamp

One-line summary of a .b1n:

$ pumpbin-cli inspect myloader/myloader.b1n --brief

myloader                 linux/exe                        0 modules

Print a language guide for embedding markers:

$ pumpbin-cli inspect loader.exe --help-markers

Converting an existing loader to work with PumpBin

Already have a working shellcode loader? You swap out the hardcoded shellcode buffer for PumpBin's marker system. Two things to get right.

  1. Your shellcode starts at index 0 after stamping.

PumpBin overwrites the entire placeholder region, including the $$SHELLCODE$$ prefix itself. Once stamped, byte 0 of your buffer is byte 0 of your shellcode. Do not skip the first 13 bytes. Do not add any offset for the marker. Read from [0].

  1. Stop the release compiler from deleting your buffer.

In Rust, wrap the functions returning your shellcode buffer and size holder in std::hint::black_box and mark them #[inline(never)]. Without those, the compiler sees "$$99999$$".parse() returns an error, concludes the shellcode length is always 0, and silently removes the entire buffer. The binary builds clean. The markers are gone. Run pumpbin-cli inspect after building to confirm they are there.

Check your work before stamping:

$ pumpbin-cli inspect yourloader.exe
verdict:   SUITABLE: ready for pumpbin-cli stamp

NOT SUITABLE means the markers are missing or the optimizer removed them. If you see NOT SUITABLE on an already-stamped implant, that is expected. The markers were consumed during stamping.

check

Pre-flight YARA scan before deploying:

$ pumpbin-cli check implant.exe --yara-rules /path/to/elastic-rules/
clean: no YARA matches in implant.exe against /path/to/elastic-rules/

Exits non-zero with matching rule names on a hit.

list-donors

Find PEs with embedded Authenticode signatures for cert-graft:

$ pumpbin-cli list-donors /Windows/System32/ --embedded-only

  embedded (1929416 B at 0x0D04B000)  /Windows/System32/MRT.exe

1 embedded, 0 catalog-only, 0 errored (43 files scanned)

Installation

git clone https://github.com/KriyosArcane/pumpbin.git
cd pumpbin
cargo build --release --bin pumpbin-cli

GUI build (Linux):

sudo apt-get install libwayland-dev libxkbcommon-dev libgtk-3-dev libssl-dev
cargo build --release --bin pumpbin --features gui

Legal

For authorized penetration testing and red team operations only. The authors accept no liability for misuse.

Acknowledgments

Based on the original b1n project. Release history: CHANGELOG.md.

About

πŸŽƒ PumpBin is an Implant Generation Platform.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Rust 99.5%
  • Other 0.5%