Active Directory data collector for BloodHound written in Rust. 🦀

Overview

RustHound

Crates.io GitHub Linux supported Windows supported macOS supported Twitter Follow Twitter Follow

Summary

Limitations

Not all SharpHound features have been implemented. Some exist in RustHound and not in SharpHound or BloodHound-Python. Please refer to the roadmap for more information.

Description

RustHound is a cross-platform BloodHound collector tool written in Rust, making it compatible with Linux, Windows, and macOS.

No AV detection and cross-compiled.

RustHound generates users, groups, computers, OUs, GPOs, containers, and domain JSON files that can be analyzed with BloodHound.

💡 If you can use SharpHound, use it. Use RustHound as a backup solution if SharpHound is detected by AV or if it not compatible with your OS.

How to compile it?

Using Makefile

You can use the make command to install RustHound or to compile it for Linux or Windows.

make install
rusthound -h

More command in the Makefile:

Default:
usage: make install
usage: make uninstall
usage: make debug
usage: make release

Static:
usage: make windows
usage: make linux_musl
usage: make macos

Dependencies:
usage: make install_windows_deps
usage: make install_linux_musl_deps
usage: make install_macos_deps

Using Dockerfile

Use RustHound with Docker to make sure to have all dependencies.

docker build -t rusthound .
docker run rusthound -h

Using Cargo

You will need to install Rust on your system.

https://www.rust-lang.org/fr/tools/install

RustHound supports Kerberos and GSSAPI. Therefore, it requires Clang and its development libraries, as well as the Kerberos development libraries. On Debian and Ubuntu, this means clang-N, libclang-N-dev, and libkrb5-dev.

For example:

# Debian/Ubuntu
sudo apt-get -y update && sudo apt-get -y install gcc libclang-dev clang libclang-dev libgssapi-krb5-2 libkrb5-dev libsasl2-modules-gssapi-mit musl-tools gcc-mingw-w64-x86-64

Here is how to compile the "release" and "debug" versions using the cargo command.

git clone https://github.com/OPENCYBER-FR/RustHound
cd RustHound
cargo build --release
# or debug version
cargo b

The result can be found in the target/release or target/debug folder.

Below you can find the compilation methodology for each of the OS from Linux. If you need another compilation system, please consult the list in this link: https://doc.rust-lang.org/nightly/rustc/platform-support.html

Manually for Linux x86_64 static version

# Install rustup and Cargo for Linux
curl https://sh.rustup.rs -sSf | sh

# Add Linux deps
rustup install stable-x86_64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-gnu

# Static compilation for Linux
git clone https://github.com/OPENCYBER-FR/RustHound
cd RustHound
CFLAGS="-lrt";LDFLAGS="-lrt";RUSTFLAGS='-C target-feature=+crt-static';cargo build --release --target x86_64-unknown-linux-gnu

The result can be found in the target/x86_64-unknown-linux-gnu/release folder.

Manually for Windows static version from Linux

# Install rustup and Cargo in Linux
curl https://sh.rustup.rs -sSf | sh

# Add Windows deps
rustup install stable-x86_64-pc-windows-gnu
rustup target add x86_64-pc-windows-gnu

# Static compilation for Windows
git clone https://github.com/OPENCYBER-FR/RustHound
cd RustHound
RUSTFLAGS="-C target-feature=+crt-static" cargo build --release --target x86_64-pc-windows-gnu

The result can be found in the target/x86_64-pc-windows-gnu/release folder.

Manually for macOS static version from Linux

Amazing documentation: https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html

# Install rustup and Cargo in Linux
curl https://sh.rustup.rs -sSf | sh

# Add macOS tool chain
sudo git clone https://github.com/tpoechtrager/osxcross /usr/local/bin/osxcross
sudo wget -P /usr/local/bin/osxcross/ -nc https://s3.dockerproject.org/darwin/v2/MacOSX10.10.sdk.tar.xz && sudo mv /usr/local/bin/osxcross/MacOSX10.10.sdk.tar.xz /usr/local/bin/osxcross/tarballs/
sudo UNATTENDED=yes OSX_VERSION_MIN=10.7 /usr/local/bin/osxcross/build.sh
sudo chmod 775 /usr/local/bin/osxcross/ -R
export PATH="/usr/local/bin/osxcross/target/bin:$PATH"

# Cargo needs to be told to use the correct linker for the x86_64-apple-darwin target, so add the following to your project’s .cargo/config file:
grep 'target.x86_64-apple-darwin' ~/.cargo/config || echo "[target.x86_64-apple-darwin]" >> ~/.cargo/config
grep 'linker = "x86_64-apple-darwin14-clang"' ~/.cargo/config || echo 'linker = "x86_64-apple-darwin14-clang"' >> ~/.cargo/config
grep 'ar = "x86_64-apple-darwin14-clang"' ~/.cargo/config || echo 'ar = "x86_64-apple-darwin14-clang"' >> ~/.cargo/config

# Static compilation for macOS
git clone https://github.com/OPENCYBER-FR/RustHound
cd RustHound
# Uncomment line 32 and comment line 34 in Cargo.toml
RUSTFLAGS="-C target-feature=+crt-static" cargo build --release --target x86_64-apple-darwin

The result can be found in the target/x86_64-apple-darwin/release folder.

Optimize the binary size

💡 To obtain an optimized compilation of RustHound add the following compilation parameters at the end of the Cargo.toml file.

[profile.release]
opt-level = "z"
lto = true
strip = true
codegen-units = 1
panic = "abort"

The size of the binary will be considerably minimized. Basic cargo compiler commands can be used.

make windows

More information here

How to build the documentation?

git clone https://github.com/OPENCYBER-FR/RustHound
cd RustHound
cargo doc --open --no-deps

Usage

Usage: rusthound [OPTIONS] --domain <domain>

Options:
  -v...          Set the level of verbosity
  -h, --help     Print help information
  -V, --version  Print version information

REQUIRED VALUES:
  -d, --domain <domain>  Domain name like: DOMAIN.LOCAL

OPTIONAL VALUES:
  -u, --ldapusername <ldapusername>  LDAP username, like: [email protected]
  -p, --ldappassword <ldappassword>  LDAP password
  -f, --ldapfqdn <ldapfqdn>          Domain Controler FQDN like: DC01.DOMAIN.LOCAL or just DC01
  -i, --ldapip <ldapip>              Domain Controller IP address like: 192.168.1.10
  -P, --ldapport <ldapport>          LDAP port [default: 389]
  -n, --name-server <name-server>    Alternative IP address name server to use for DNS queries
  -o, --output <output>              Output directory where you would like to save JSON files [default: ./]

OPTIONAL FLAGS:
      --ldaps           Force LDAPS using for request like: ldaps://DOMAIN.LOCAL/
      --dns-tcp         Use TCP instead of UDP for DNS queries
      --dc-only         Collects data only from the domain controller. Will not try to retrieve CA security/configuration or check for Web Enrollment
      --old-bloodhound  For ADCS only. Output result as BloodHound data for the original BloodHound version from @BloodHoundAD without PKI support
  -z, --zip             Compress the JSON files into a zip archive

OPTIONAL MODULES:
      --fqdn-resolver  Use fqdn-resolver module to get computers IP address
      --adcs           Use ADCS module to enumerate Certificate Templates, Certificate Authorities and other configurations.
                       (For the custom-built BloodHound version from @ly4k with PKI support)

Demo

Examples are done on the GOADv2 implemented by mayfly:

Simple usage

# Linux with username:password
rusthound -d north.sevenkingdoms.local -u '[email protected]' -p '_L0ngCl@w_' -o /tmp/demo -z

# Linux with username:password and ldapip
rusthound -d north.sevenkingdoms.local -i 192.168.56.11 -u '[email protected]' -p '_L0ngCl@w_' -o /tmp/demo -z

# Linux with username:password and ldaps
rusthound -d north.sevenkingdoms.local --ldaps -u '[email protected]' -p '_L0ngCl@w_' -o /tmp/demo -z 
# Linux with username:password and ldaps and custom port
rusthound -d north.sevenkingdoms.local --ldaps -P 3636 -u '[email protected]' -p '_L0ngCl@w_' -o /tmp/demo -z 

# Tips to redirect and append both standard output and standard error to a file > /tmp/rh_output 2>&1
rusthound -d north.sevenkingdoms.local --ldaps -u '[email protected]' -p '_L0ngCl@w_' -o /tmp/demo --fqdn-resolver > /tmp/rh_output 2>&1

# Windows with GSSAPI session
rusthound.exe -d sevenkingdoms.local --ldapfqdn kingslanding
# Windows simple bind connection username:password (do not use single or double quotes with cmd.exe)
rusthound.exe -d sevenkingdoms.local -u [email protected] -p _L0ngCl@w_ -o output -z

Module FQDN resolver

# Linux with username:password and FQDN resolver module
rusthound -d essos.local -u '[email protected]' -p 'BurnThemAll!' -o /tmp/demo --fqdn-resolver -z
# Linux with username:password and ldaps and FQDN resolver module and TCP DNS request and custom name server
rusthound -d essos.local --ldaps -u '[email protected]' -p 'BurnThemAll!' -o /tmp/demo --fqdn-resolver --tcp-dns --name-server 192.168.56.12 -z

# Windows with GSSAPI session and FQDN resolver module
rusthound.exe -d essos.local -f meereen -o output --fqdn-resolver -z
# Windows simple bind connection username:password and FQDN resolver module and TCP DNS request and custom name server (do not use single or double quotes with cmd.exe)
rusthound.exe -d essos.local -u [email protected] -p BurnThemAll! -o output -z --fqdn-resolver --tcp-dns --name-server 192.168.56.12 

Module ADCS collector

Example using @ly4k BloodHound version.

# Linux with username:password and ADCS module for @ly4k BloodHound version
rusthound -d essos.local -u '[email protected]' -p 'BurnThemAll!' -o /tmp/adcs --adcs -z
# Linux with username:password and ADCS module and dconly flag (will don't check webenrollment)
rusthound -d essos.local -u '[email protected]' -p 'BurnThemAll!' -o /tmp/adcs --adcs --dc-only -z

# Linux with username:password and ADCS module using "--old-bloodhound" argument for official @BloodHoundAd version
rusthound -d essos.local -u '[email protected]' -p 'BurnThemAll!' -o /tmp/adcs --adcs --old-bloodhound -z

# Windows with GSSAPI session and ADCS module
rusthound.exe -d essos.local -f meereen -o output -z --adcs
# Windows with GSSAPI session and ADCS module and TCP DNS request and custom name server
rusthound.exe -d essos.local --ldapfqdn meereen -o output -z --adcs --tcp-dns --name-server 192.168.56.12
# Windows simple bind connection username:password (do not use single or double quotes with cmd.exe)
rusthound.exe -d essos.local -u [email protected] -p BurnThemAll! -o output -z --adcs --dc-only

You can find the custom queries used in the demo in the resource folder.

Use the following command to install it:

cp resources/customqueries.json ~/.config/bloodhound/customqueries.json

🚀 Statistics

In order to make statistics on a DC with more LDAP objects, run the BadBlood on the domain controller ESSOS.local from GOAD. The DC should now have around 3500 objects. Below is the average time it takes to run the following tools:

Tool Environment Objects Time Command
SharpHound.exe Windows ~3500 ~51.605s Measure-Command { sharphound.exe -d essos.local --ldapusername 'khal.drogo' --ldappassword 'horse' --domaincontroller '192.168.56.12' -c All }
BloodHound.py Linux ~3500 ~9.657s time python3 bloodhound.py -u khal.drogo -p horse -d essos.local -ns 192.168.56.12 --zip -c all
RustHound.exe Windows ~3500 ~5.315s Measure-Command { rusthound.exe -d essos.local -u [email protected] -p horse -z }
RustHound Linux ~3500 ~3.166s time rusthound -d essos.local -u [email protected] -p horse -z

🚥 Roadmap

Authentification

  • LDAP (389)
  • LDAPS (636)
  • BIND
  • NTLM
  • GSSAPI for Windows ok, but not tested on Linux

Outputs

  • users.json
  • groups.json
  • computers.json
  • ous.json
  • gpos.json
  • containers.json
  • domains.json
  • cas.json
  • templates.json
  • args and function to zip JSON files --zip

Modules

  • Retreive LAPS password if your user can read them automatic
  • Resolve FQDN computers found to IP address --fqdn-resolver
  • Retrieve certificates for ESC exploitation with Certipy --adcs
  • Kerberos attack module (ASREPROASTING and KERBEROASTING) --attack-kerberos
  • Retrieve datas from trusted domains --follow-trust (Currently working on it, got beta version of this module)

BloodHound v4.2

  • Parsing Features

    • Users & Computers
      • HasSIDHistory
    • Users
      • Properties : sfupassword
  • DCERPC (dependencies)

    • Computers
      • Sessions
    • OUs & Domains
      • LocalAdmins
      • RemoteDesktopUsers
      • DcomUsers
      • PSRemoteUsers
    • CAs
      • User Specified SAN
      • Request Disposition

🔗 Links

Comments
  • Unique issue with too many LDAP objects - [BUG]

    Unique issue with too many LDAP objects - [BUG]

    Hey there, love the idea of this tool!

    I've run into an issue, which might not be as common enough to warrant a true fix, but when running in a domain with 100's of thousands of LDAP objects, the process ends up dying around averagely around 410k objects retrieved

    [2022-12-29T16:21:17Z INFO  rusthound::ldap] Starting data collection...
    LDAP objects retreived: 405944#                                                                                                                                           
    56821 killed     target/release/rusthound -d xxx.com -u 'xxxxx' -p  --adcs -```
    
    
    [2022-12-29T18:24:42Z INFO  rusthound::ldap] Starting data collection...
    ⢀ LDAP objects retreived: 56783#                                                                                                               
    .  LDAP objects retreived: 57480#                                                                                                               
    ⠐ LDAP objects retreived: 429216#                                                                                                              
    Killed
    $ 
    

    Let me know if you'd like any other data points!

    opened by AnubisSec 4
  • Failed to authenticate - invalidCredentials

    Failed to authenticate - invalidCredentials

    Hello,

    I'm currently testing RustHound on the Resolute Box from Hack the Box and I ran into an error and I don't get why it's happening.

    CME Result:

    [Feb 12, 2023 - 17:35:10 (CET)] exegol-htb-resolute /workspace # cme smb $TARGET
    SMB         10.129.217.23   445    RESOLUTE         [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
    

    BloodHound.py:

    [Feb 12, 2023 - 17:50:09 (CET)] exegol-htb-resolute /workspace # bloodhound.py -d megabank.local -u 'ryan' -p 'password' -ns 10.129.217.23
    INFO: Found AD domain: megabank.local
    INFO: Connecting to LDAP server: Resolute.megabank.local
    INFO: Found 1 domains
    INFO: Found 1 domains in the forest
    INFO: Found 2 computers
    INFO: Found 28 users
    INFO: Connecting to LDAP server: Resolute.megabank.local
    INFO: Found 54 groups
    INFO: Found 0 trusts
    INFO: Starting computer enumeration with 10 workers
    INFO: Querying computer: MS02.megabank.local
    INFO: Querying computer: Resolute.megabank.local
    INFO: Done in 00M 03S
    

    RustHound:

    [Feb 12, 2023 - 17:50:36 (CET)] exegol-htb-resolute /workspace # rusthound -d megabank.local -u 'ryan' -p 'password' -n 10.129.217.23 -i 10.129.217.23
    ---------------------------------------------------
    Initializing RustHound at 17:50:56 on 02/12/23
    Powered by g0h4n from OpenCyber
    ---------------------------------------------------
    
    [2023-02-12T16:50:56Z INFO  rusthound] Verbosity level: Info
    [2023-02-12T16:50:56Z ERROR rusthound::ldap] Failed to authenticate to MEGABANK.LOCAL Active Directory. Reason: LDAP operation result: rc=49 (invalidCredentials), dn: "", text: "80090308: LdapErr: DSID-0C09042A, comment: AcceptSecurityContext error, data 52e, v3839"
    

    What am I missing ?

    opened by Techbrunch 3
  • Installation

    Installation "Failed to Download Rustls v0.20.6"

    In attempting to install RustHound, hit an error and stated that it "failed to download rustls v0.20.6"

    error: failed to download `rustls v0.20.6`
    
    Caused by:
      unable to get packages from source
    
    Caused by:
      failed to parse manifest at `**/registry/src/github.com-1ecc6299db9ec823/rustls-0.20.6/Cargo.toml`
    
    Caused by:
      feature `resolver` is required
    
      consider adding `cargo-features = ["resolver"]` to the manifest
    

    Steps to reproduce

    1. Grab the latest from GitHub via git clone <>
    2. cd <>
    3. cargo build --release as discussed in URL

    Current version(s):

    • Cargo 1.46.0

    Please let me know if there is anything I can do to help with this error or if you need more information. Thank you!

    opened by stevesec 3
  • lockfile

    lockfile

    Could you provide the dependency lockfile so we could build it with cargo build --release --locked?

    The lockfile is highly important so the build is reproducible.

    opened by noraj 1
  • Progress bar feauture

    Progress bar feauture

    Please add a progress bar as in SharpHound. That would be awesome. Today I tried to use a rusthound on domain and I waited for a couple of mins without any indication. So I checked wireshark for ldap requests that how I understood that something's happening.

    opened by hesoyamimi 1
  • Missing ACE

    Missing ACE

    Some ACEs were missing on one of my labs. The padding was not taken into consideration on the ACE datas part. And found ACE with null SID like DOMAIN-S-0-0

    https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/628ebb1d-c509-4ea0-a10f-77ef97ca4586

    struct ACE {
        uint8   AceType;
        uint8   AceFlags;
        uint16  AceSize;
        char    Data[AceSize - 4];
    };
    

    I found my error which was about the size of the data retrieved by RustHound for an ACE.

    I changed completely the code of secdesc.rs to fixed the error and to use the new version of nom7 as suricata does to parse the network packet data.

    bug 
    opened by g0h4n 0
  • Hanging When Retrieving LDAP Objects

    Hanging When Retrieving LDAP Objects

    Hi, When running RustHound against a large domain, RustHound eventually hangs at "LDAP objects received: xxxxx". The TCP/389 connection is still open (observed via tcpdump) but it appears the DC stops sending data (for an unknown reason) and just sends ACKs. In the following code block, it appears RustHound just continues to wait indefinitely. Perhaps a timeout could be set and RustHound can resend the request if it hasn't received a response by the timeout?

    // Wait and get next values
    let pb = ProgressBar::new(1);
    let mut count = 0;	
    while let Some(entry) = search.next().await? {
    	let entry = SearchEntry::construct(entry);
    	//trace!("{:?}", &entry);
    	// Manage progress bar
    	count += 1;
    	progress_bar(pb.to_owned(),"LDAP objects retreived".to_string(),count,"#".to_string());	
    	// Push all result in rs vec()
    	rs.push(entry);
    }
    pb.finish_and_clear();
    
    opened by quantumburnz 2
Owner
OPENCYBER
Founded in 2012, OPENCYBER is an independent information systems security firm specializing in penetration testing and technical security audits.
OPENCYBER
A small Rust library that let's you get position and size of the active window on Windows and MacOS

active-win-pos-rs A small Rust library that let's you get position and size of the active window on Windows and MacOS Build % git clone https://github

Dmitry Malkov 21 Jan 6, 2023
Umpteen is a general-purpose programming language currently in active development being bootstrapped from Rust

The Umpteen Programming Language This repository provides the reference implementation for the Umpteen Programming Language, bootstrapped from Rust. U

Katie Janzen 4 Nov 20, 2023
An easy-to-use, incremental, multi-threaded garbage collector for Rust

Refuse An easy-to-use, incremental, multi-threaded garbage collector for Rust. //! A basic usage example demonstrating the garbage collector. use refu

Khonsu Labs 6 May 3, 2024
Nvm - Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions

Node Version Manager Table of Contents Intro About Installing and Updating Install & Update Script Additional Notes Troubleshooting on Linux Troublesh

nvm.sh 63.8k Jan 7, 2023
Show active TCP connections on a TUI world map.

Maperick Show active TCP connections on a TUI world map. Still WIP, but it's gonna be good. Setup git clone [email protected]:schlunsen/maperick.git cd m

Rasmus Schlünsen 5 Jul 8, 2022
Tracing layer that automatically creates and manages progress bars for active spans.

tracing-indicatif A tracing layer that automatically creates and manages indicatif progress bars for active spans. Progress bars are a great way to ma

Emerson Ford 95 Feb 22, 2023
An implementation of a Windows Event Collector server running on GNU/Linux.

OpenWEC OpenWEC is a free and open source (GPLv3) implementation of a Windows Event Collector server running on GNU/Linux and written in Rust. OpenWEC

CEA IT Security 15 Jun 15, 2023
Dead simple, memoized cargo subcommand to hoist cargo-built binaries into the current working directory, written in Rust.

cargo-hoist Dead simple cargo subcommand to hoist cargo-built binaries into scope. stable Install | User Docs | Crate Docs | Reference | Contributing

refcell.eth 6 Nov 9, 2023
dua (-> Disk Usage Analyzer) is a tool to conveniently learn about the usage of disk space of a given directory

dua (-> Disk Usage Analyzer) is a tool to conveniently learn about the usage of disk space of a given directory. It's parallel by default and will max

Sebastian Thiel 1.8k Jan 2, 2023
To help prevent directory traversal attacks

safe_join Use SafeJoin::safe_join in place of Path::join to help prevent directory traversal attacks. A call of the form dir.safe_join(path) returns a

Trail of Bits 1 Dec 27, 2021
Jumpy is a tool that allows to quickly jump to one of the directory you've visited in the past

Jumpy Jumpy is a tool that allows to quickly jump to one of the directory you've visited in the past. It is heavily inspired by Zoxide but is more lig

Clément Nerma 2 Oct 3, 2022
A simple command line program to upload file or directory to web3.storage with optional encryption and compression

w3s-cli A simple command line program to upload file or directory to web3.storage with optional encryption and compression. Features Uploads single fi

qdwang 5 Oct 22, 2022
Minimal recursive "truncate file/directory names to meet requirements" tool

trunc_filenames ssokolow@monolith ~ % trunc_filenames --help trunc_filenames 0.1.0 Rename files and directories to fit length limits. WARNING: Will n

Stephan Sokolow 2 Nov 20, 2022
Periodically download a youtube playlist, extract audio, convert to mp3, move to directory (possibly synced using syncthing).

auto-dl Periodically download a youtube playlist, extract audio, convert to mp3, move to directory (possibly synced using syncthing). drop https://git

Paul Adenot 10 Jan 12, 2023
A simple tool to clean all projects in a directory.

Cargo Cleanall A simple tool to clean all cargo projects in a directory. Help Cargo plugin to clean all cargo projects in a directory Usage: cargo cl

null 11 Jan 24, 2023
Rsre it's tool to rename file/directory

, Rust renamer Rsre it's tool to rename file/directory Zero dependencies ?? Requirements Rust Nightly Install With Cargo # Install nightly rust rustup

Awiteb 6 Dec 22, 2022
Bookmark directories for easy directory-hopping in the terminal

markd Bookmark directories for easy directory-hopping in the terminal. All it takes is one command markd to bookmark your current directory, or use th

Maaz Ahmed 10 Jul 10, 2023
Convert your .NET dependencies to the Directory.Packages.props format

directory-packages-props-converter Converts your projects to use Central Package Management. <PackageReference> dependencies have their Version remove

Jeroen Vannevel 18 Aug 7, 2023
⚡️(cd with env) Is a configurable cd wrapper that lets you define your environment per directory.

⚡️cdwe (cd with env) A simple configurable cd wrapper that provides powerful utilities for customizing your envionment per directory. (For ZSH / BASH

teo 20 Aug 6, 2023