Skip to main content

pypi package GitHub

Search for dependencies inside a compiled rust executable, download them and create a signature.

  • Allows you to create a signature out of dependencies and proper rust stdlib, using the right toolchain.
  • Give information about the version of the compiler used
  • Give information about detected dependencies used
  • Allows you to easily download a crate
Before After
Before After

Install

git clone https://github.com/N0fix/rustbinsign
cd rustbinsign
poetry install
rustbinsign --help

Help

usage: rbs [-h] [-l {DEBUG,INFO,WARNING,ERROR,CRITICAL}] {info,download,download_sign,download_compile,compile,compile_target,sign_stdlib,sign_target,sign_libs,get_std_lib,guess_project_creation_timestamp} ...

This script aims at facilitate creation of signatures for rust executables. It can detect dependencies and rustc version used in a target, and create signatures using a signature provider.

options:
  -h, --help            show this help message and exit
  -l {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --log {DEBUG,INFO,WARNING,ERROR,CRITICAL}
                        Set the logging level

mode:
  {info,download,download_sign,download_compile,compile,compile_target,sign_stdlib,sign_target,sign_libs,get_std_lib,guess_project_creation_timestamp}
                        Mode to use
    info                Get information about an executable
    download            Download a crate. Exemple: rand_chacha-0.3.1
    download_compile    Download a crate and compiles it. Exemple: rand_chacha-0.3.1
    download_sign       Download a crate, compiles it and signs it. Exemple: rand_chacha-0.3.1
    compile             Compiles a crate. Exemple: rand_chacha-0.3.1
    compile_target      Compiles all dependencies detected in target compiled rust executable.
    sign_stdlib         Sign standard lib toolchain.
    sign_target         Generate a signature for a given executable, using choosed signature provider.
    sign_libs           Generate a signature for a given list of libs, using choosed signature provider.
    get_std_lib         Download stdlib with symbols for a specific version of rustc.
    guess_project_creation_timestamp
                        Tries to guess the compilation date based on dependencies version.

Usage examples:

 rustbinsign -l DEBUG info 'challenge.exe'
 rustbinsign -l DEBUG download_sign --provider IDA hyper-0.14.27 1.70.0-x86_64-unknown-linux-gnu
 rustbinsign -l DEBUG download hyper-0.14.27
 rustbinsign -l DEBUG download_compile rand_chacha-0.3.1 1.70.0-x86_64-unknown-linux-gnu
 rustbinsign -l DEBUG compile --template ./profile/ctf.json /tmp/rustbininfo/rand_chacha-0.3.1/Cargo.toml 1.70.0-x86_64-unknown-linux-gnu
 rustbinsign -l DEBUG sign_stdlib --template ./profiles/ivanti_rust_sample.json -t 1.70.0-x86_64-unknown-linux-musl --provider IDA
 rustbinsign -l DEBUG get_std_lib 1.70.0-x86_64-unknown-linux-musl
 rustbinsign -l DEBUG sign_libs -l .\sha2-0.10.8\target\release\sha2.lib -l .\crypt-0.4.2\target\release\crypt.lib --provider IDA
 rustbinsign -l DEBUG sign_target -t stable-x86_64-pc-windows-gnu --template ./profiles/target.json  --provider IDA --target ./target.exe --no-std --signature_name target_sig

Example usage

Info

$ rbs info sample.bin
TargetRustInfo(
    rustc_version='1.70.0',
    rustc_commit_hash='90c541806f23a127002de5b4038be731ba1458ca',
    dependencies=[
        Crate(name='addr2line', version='0.17.0', features=[], repository=None),
        Crate(name='aes', version='0.7.5', features=[], repository=None),
        Crate(name='bytes', version='1.4.0', features=[], repository=None),
        Crate(name='cfb-mode', version='0.7.1', features=[], repository=None),
        Crate(name='crossbeam-channel', version='0.5.8', features=[], repository=None),
        Crate(name='crossbeam-deque', version='0.8.3', features=[], repository=None),
        Crate(name='crossbeam-epoch', version='0.9.15', features=[], repository=None),
        Crate(name='futures-channel', version='0.3.28', features=[], repository=None),
        Crate(name='futures-core', version='0.3.28', features=[], repository=None),
        Crate(name='futures-util', version='0.3.28', features=[], repository=None),
        Crate(name='generic-array', version='0.14.7', features=[], repository=None),
        Crate(name='gimli', version='0.26.2', features=[], repository=None),
        Crate(name='hashbrown', version='0.12.3', features=[], repository=None),
        Crate(name='hex', version='0.4.3', features=[], repository=None),
        Crate(name='http', version='0.2.9', features=[], repository=None),
        Crate(name='httparse', version='1.8.0', features=[], repository=None),
        Crate(name='hyper', version='0.14.27', features=[], repository=None),
        Crate(name='mio', version='0.8.8', features=[], repository=None),
        Crate(name='once_cell', version='1.18.0', features=[], repository=None),
        Crate(name='rayon', version='1.7.0', features=[], repository=None),
        Crate(name='rayon-core', version='1.11.0', features=[], repository=None),
        Crate(name='self-replace', version='1.3.5', features=[], repository=None),
        Crate(name='socket2', version='0.4.9', features=[], repository=None),
        Crate(name='sysinfo', version='0.29.2', features=[], repository=None),
        Crate(name='tokio', version='1.29.0', features=[], repository=None),
        Crate(name='want', version='0.3.1', features=[], repository=None)
    ],
    rust_dependencies_imphash='4b15dc8e43b773df8900e7b194ada169',
    guessed_toolchain='Mingw-w64 (Mingw6-GCC_8.3.0)'
)

This can be used to apply the proper signature.

Some signatures of rust win stdlib are available here.

Requirements

You have to build on the same platform then the platform used to build your target (likely linux if your target is an ELF, likely windows if your target is an EXE). Choosing IDA as your signature provider requires IDA with IDAPython. IDA provider is the only provider supported at the moment.

Extending the tool for other disassemblers

This tool is meant to be used with IDA. If you want to extend it to Ghidra, binja, r2, or watever tool you are using, just create a new provider that inherits BaseSigProvider. You might need to adapt the command line to add your provider's argument.

TODO (hopefully ?)

  • Make a Dockerfile for easy installation and usage
  • Make Dockerfiles to easy usage when signing mingw targets
  • Implement a provider that does not require IDA with IDAPython, using smda

FAQ

How is it different from Ariane or Cerberus?

While Ariane or Cerberus tries to recognize functions and sign them themselves, reinventing the wheel, this tool focuses on providing accurate information about the Rust compiler (rustc) version used in your target, as well as its dependencies. I delegate function recognition and signature tasks to tools specifically designed for those purposes (IDA, binja...). These tasks are incredibly complex to execute correctly, and these tools perform them much more effectively than I could.

How can I adapt it to Ghidra/Binary Ninja/X ?

This tool generates a signature using a signature provider defined under sig_providers/. You should be able to effortlessly add your own provider to generate a signature that your favorite tool will recognize.

Limitations

Limitations are described in this blogpost.

Thanks

This tool uses the great Mandiant's idb2pat.

Metadata

Release files for rustbinsign 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rustbinsign 0.1.1
File Size Uploaded Provenance
rustbinsign-0.1.1.tar.gz 28.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for rustbinsign 0.1.1
File Interpreter ABI Platform
rustbinsign-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 62.9 kB

Release files / rustbinsign-0.1.1.tar.gz

Download URL rustbinsign-0.1.1.tar.gz
Size 28.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3b853c9df68f7dfd47d2ded83ec2635bbbbb015494fd7a86447337ad89d3718d
BLAKE2b-256 checksum
How to use checksums
41b8a7e8c6b361de3c21a98556506997188160117f9376e268e2008da1bf8191
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.11.2 Linux/6.2.0-39-generic

Release files / rustbinsign-0.1.1-py3-none-any.whl

Download URL rustbinsign-0.1.1-py3-none-any.whl
Size 34.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ea6b56c3114602b358fd4d887ba404301b39533bb6e31a77208dd5b22703fcce
BLAKE2b-256 checksum
How to use checksums
ae61ba802cf58d1ca43dfe092161d623c501dd7ab2fefa580164d973fa8e35bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.11.2 Linux/6.2.0-39-generic

Security for rustbinsign 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page