xgadget

crates.io GitHub Actions

Fast, parallel, cross-variant ROP/JOP gadget search for x86 (32-bit) and x64 (64-bit) binaries. Uses the iced-x86 disassembler library.

Current state: decent test coverage, but still in beta. Issues/PRs welcome :)

Quickstart

Install the CLI tool and show its help menu:

bash cargo install xgadget --features cli-bin # Build on host (pre-req: https://www.rust-lang.org/tools/install) xgadget --help # List available commandline options

About

xgadget is a tool for Return-Oriented Programming (ROP) and Jump-Oriented Programming (JOP) exploit development. It's a fast, multi-threaded alternative to awesome tools like ROPGadget, Ropper, and rp.

Though not yet as mature as some of its contemporaries, it contains unique and experimental functionality. To the best of our knowledge, xgadget is the first gadget search tool to have these features:

Other features include:

API Usage

Find gadgets:

```rust use xgadget;

let maxgadgetlen = 5;

// Search single binary let searchconfig = xgadget::SearchConfig::DEFAULT; let bin1 = xgadget::Binary::frompathstr("/path/to/binv1").unwrap(); let bins = vec![bin1]; let gadgets = xgadget::findgadgets(&bins, maxgadgetlen, searchconfig).unwrap(); let stackpivotgadgets = xgadget::filterstackpivot(&gadgets);

// Search for cross-variant gadgets, including partial matches let searchconfig = xgadget::SearchConfig::DEFAULT | xgadget::SearchConfig::PART; let bin1 = xgadget::Binary::frompathstr("/path/to/binv1").unwrap(); let bin2 = xgadget::Binary::frompathstr("/path/to/binv2").unwrap(); let bins = vec![bin1, bin2]; let crossgadgets = xgadget::findgadgets(&bins, maxgadgetlen, searchconfig).unwrap(); let crossregpopgadgets = xgadget::filterregpoponly(&cross_gadgets); ```

Custom filters can be created using the GadgetAnalysis object and/or functions from the semantics module. How the above filter_stack_pivot function is implemented:

```rust use rayon::prelude::*; use iced_x86; use xgadget::{Gadget, GadgetAnalysis};

/// Parallel filter to gadgets that write the stack pointer pub fn filterstackpivot<'a>(gadgets: &[Gadget<'a>]) -> Vec> { gadgets .pariter() .filter(|g| { let regsoverwritten = GadgetAnalysis::new(&g).regsoverwritten(); if regsoverwritten.contains(&icedx86::Register::RSP) || regsoverwritten.contains(&icedx86::Register::ESP) || regsoverwritten.contains(&iced_x86::Register::SP) { return true; } false }) .cloned() .collect() } ```

CLI Usage

Run xgadget --help:

``` xgadget v0.6.0

About: Fast, parallel, cross-variant ROP/JOP gadget search for x86/x64 binaries. Cores: 8 logical, 8 physical

USAGE: xgadget [OPTIONS]

ARGS:

OPTIONS: -a, --arch For raw (no header) files: specify arch ('x8086', 'x86', or 'x64') [default: x64] -b, --bad-bytes Filter to gadgets matching a regular expression -h, --help Print help information --inc-call Include gadgets containing a call [default: don't include] --inc-imm16 Include '{ret, ret far} imm16' (e.g. add to stack ptr) [default: don't include] -j, --jop Search for JOP gadgets only [default: ROP, JOP, and SYSCALL] -l, --max-len Gadgets up to LEN instrs long. If 0: all gadgets, any length [default: 5] -m, --partial-match Include cross-variant partial matches [default: full matches only] -n, --no-color Don't color output [default: color output] --no-deref [] Filter to gadgets that don't deref any regs or a specific reg [default: all] -p, --stack-pivot Filter to gadgets that write the stack ptr [default: all] --param-ctrl Filter to gadgets that control function parameters [default: all] -r, --rop Search for ROP gadgets only [default: ROP, JOP, and SYSCALL] --reg-ctrl [] Filter to gadgets that control any reg or a specific reg [default: all] --reg-pop Filter to 'pop {reg} * 1+, {ret or ctrl-ed jmp/call}' gadgets [default: all] -s, --sys Search for SYSCALL gadgets only [default: ROP, JOP, and SYSCALL] -t, --att Display gadgets using AT&T syntax [default: Intel syntax] -V, --version Print version information ```

CLI Build and Install (Recommended)

Build a dynamically-linked binary from source and install it locally:

bash cargo install xgadget --features cli-bin # Build on host (pre-req: https://www.rust-lang.org/tools/install)

CLI Binary Releases for Linux

Commits to this repo's master branch automatically run integration tests and build a statically-linked binary for 64-bit Linux. You can download it here to try out the CLI immediately, instead of building from source. Static binaries for Windows may also be supported in the future.

Unfortunately the statically-linked binary is several times slower on an i7-9700K, likely due to the built-in memory allocator for target x86_64-unknown-linux-musl. So building a dynamically-linked binary from source with the above cargo install command is highly recommended for performance (links against your system's allocator).

Why No Chain Generation?

Tools that attempt to automate ROP/JOP chain generation require heavyweight analysis - typically symbolic execution of an intermediate representation. While this works well for small binaries and CTF problems, but tends to be error-prone and difficult to scale for large, real-world programs. At present, xgadget has a different goal: enable an expert user to manually craft stable exploits by providing fast, accurate gadget discovery.

~~Yeah, but can it do 10 OS kernels under 10 seconds?!~~ Repeatable Benchmark Harness

bash bash ./benches/bench_setup_ubuntu.sh # Ubuntu-specific, download/build 10 kernel versions cargo bench # Grab a coffee, this'll take a while...

On an i7-9700K (8C/8T, 3.6GHz base, 4.9 GHz max) machine with gcc version 8.4.0: the average runtime, to process all ten 54MB kernels simultaneously with a max gadget length of 5 instructions and full-match search for all gadget types (ROP, JOP, and syscall gadgets), is only 6.3 seconds! Including partial matches as well takes just 7.9 seconds.

Acknowledgements

This project started as an optimized solution to Chapter 8, exercise 3 of "Practical Binary Analysis" by Dennis Andreisse [6], and builds on the design outlined therein.

License and Contributing

Licensed under the MIT license. Contributions are welcome!

References