rusthound-ce.md (13688B)
1 --- 2 title: "RustHound-CE" 3 description: "Cross-platform BloodHound Community Edition collector written in Rust. Fast LDAP-based AD enumeration with pass-the-hash, Kerberos, certificate auth and ADCS-aware output." 4 category: active-directory 5 subcategory: "Tooling & Recon" 6 tags: ["active-directory", "kerberos", "adcs"] 7 tools: ["RustHound-CE", "BloodHound", "SharpHound", "Impacket", "faketime"] 8 difficulty: intermediate 9 updated: "2026-09-13" 10 source: "vault:ActiveDirectory/RustHound-CE_Cheatsheet.md" 11 --- 12 13 # ๐ฆ RustHound-CE Cheatsheet 14 15 > **Complete guide to using RustHound-CE for BloodHound Community Edition data collection.** 16 17 RustHound-CE is a fast, cross-platform BloodHound **Community Edition** collector written in Rust, maintained by **g0h4n**. It talks to a Domain Controller over LDAP/LDAPS from Linux, macOS or Windows and emits CE-schema JSON (optionally zipped) for ingestion into the BloodHound CE web UI. 18 19 > [!warning] CE-only output schema 20 > RustHound-CE produces **BloodHound CE** JSON, which is **not** interchangeable with legacy BloodHound. For legacy BloodHound, use the separate NeverHack-maintained RustHound (original), `bloodhound-python`, or SharpHound v1. Uploading the wrong schema silently fails or mis-parses. 21 22 Related notes: SharpHound, bloodhound-ce-python, BloodHound, NetExec, Impacket, faketime, Kerberos Tickets. 23 24 --- 25 26 ## ๐ Table of Contents 27 28 - [Overview](#-overview) 29 - [Installation](#-installation) 30 - [CLI Options Reference](#-cli-options-reference) 31 - [Basic Usage](#-basic-usage) 32 - [Authentication Methods](#-authentication-methods) 33 - [Collection Methods](#-collection-methods) 34 - [Performance & Reliability](#-performance--reliability) 35 - [DNS & Host Resolution](#-dns--host-resolution) 36 - [Time Skew & Kerberos Gotchas](#-time-skew--kerberos-gotchas) 37 - [Ingesting into BloodHound CE](#-ingesting-into-bloodhound-ce) 38 - [SharpHound / bloodhound-python Equivalents](#-sharphound--bloodhound-python-equivalents) 39 - [Troubleshooting](#-troubleshooting) 40 - [OPSEC Notes](#-opsec-notes) 41 42 --- 43 44 ## ๐ฏ Overview 45 46 **RustHound-CE** enumerates Active Directory over LDAP to map attack paths, ACLs, sessions, trusts and (optionally) ADCS relationships for BloodHound CE. 47 48 ### Key features 49 - โ Single static binary, no .NET / Python runtime needed 50 - โ Cross-platform: Linux, macOS, Windows, ARM 51 - โ Runs remotely from a non-domain-joined attacker host 52 - โ Password, NTLM hash (pass-the-hash), Kerberos ccache, and client-certificate auth 53 - โ LDAPS support and custom LDAP filters 54 - โ On-disk caching and `--resume` for large / flaky environments 55 - โ Outputs CE-compatible JSON, optionally zipped for direct upload 56 57 ### Compatibility 58 - **Targets:** BloodHound **Community Edition** only. 59 - **Legacy BloodHound:** use the original RustHound (NeverHack) or `bloodhound-python`. 60 - Always match collector output to your BloodHound server version; check the CE web UI under **Settings โ Download Collectors** for the expected format. 61 62 --- 63 64 ## ๐ฆ Installation 65 66 ### Via Cargo (recommended) 67 ```bash 68 cargo install rusthound-ce 69 # binary lands in ~/.cargo/bin/rusthound-ce 70 ``` 71 72 ### Build dependencies (Debian/Ubuntu/Kali) 73 ```bash 74 sudo apt install -y gcc clang libclang-dev \ 75 libgssapi-krb5-2 libkrb5-dev libsasl2-modules-gssapi-mit \ 76 musl-tools gcc-mingw-w64-x86-64 77 ``` 78 The Kerberos and SASL packages are needed for `-k` (GSSAPI) auth; the musl and mingw toolchains are only needed for static / cross-compiled builds. 79 80 ### From source 81 ```bash 82 git clone https://github.com/g0h4n/RustHound-CE 83 cd RustHound-CE 84 85 make release # optimized build for the current system 86 # or 87 cargo build --release 88 ``` 89 90 ### Makefile cross-compile targets 91 ```bash 92 make windows # cross-compile a Windows .exe 93 make linux_musl # static Linux binary (portable, no libc deps) 94 make linux_aarch64 # ARM64 Linux 95 make armv7 # ARMv7 96 make macos # macOS 97 make install # install locally / make uninstall to remove 98 ``` 99 100 ### Docker 101 ```bash 102 # build the image, then run against the current dir as output volume 103 docker run --rm -v "$PWD":/usr/src/rusthound-ce rusthound-ce \ 104 -d domain.local -u user@domain.local -p 'Password123' -o /usr/src/rusthound-ce -z 105 ``` 106 107 --- 108 109 ## ๐งฐ CLI Options Reference 110 111 ``` 112 rusthound-ce [OPTIONS] --domain <domain> 113 ``` 114 115 | Flag | Long form | Description | 116 |:-----|:----------|:------------| 117 | `-d` | `--domain <domain>` | **Required.** Domain FQDN, e.g. `DOMAIN.LOCAL` | 118 | `-u` | `--ldapusername <user>` | LDAP username, e.g. `user@domain.local` | 119 | `-p` | `--ldappassword <pass>` | LDAP password | 120 | `-H` | `--hashes <hashes>` | NT hash for pass-the-hash (NTLM) | 121 | `-k` | `--kerberos` | Kerberos auth via ccache (`KRB5CCNAME`) | 122 | `-f` | `--ldapfqdn <fqdn>` | DC FQDN, e.g. `DC01.DOMAIN.LOCAL` or just `DC01` | 123 | `-i` | `--ldapip <ip>` | Domain Controller IP address | 124 | `-P` | `--ldapport <port>` | LDAP port (default `389`, or `636` with `--ldaps`) | 125 | | `--ldaps` | Force LDAPS (TLS) for requests | 126 | | `--dns-tcp` | Use TCP instead of UDP for DNS queries | 127 | `-n` | `--name-server <ip>` | Alternative DNS server IP | 128 | | `--pfx <pfx>` | PFX / PKCS#12 client certificate | 129 | | `--pfx-pass <pass>` | PFX file password (optional) | 130 | | `--crt <crt>` | PEM client certificate | 131 | | `--key <key>` | PEM private key | 132 | `-o` | `--output <dir>` | Output directory (default `./`) | 133 | `-z` | `--zip` | Compress JSON files into a single archive | 134 | `-c` | `--collectionmethod [<M>]` | `All` (LDAP,SMB,HTTP) or `DCOnly` (default `All`) | 135 | | `--cache` | Cache LDAP results to disk | 136 | | `--cache-buffer <n>` | Buffer size when caching (default `1000`) | 137 | | `--resume` | Resume from last saved state | 138 | | `--ldap-filter <filter>` | Custom LDAP filter (default `(objectClass=*)`) | 139 | | `--fqdn-resolver` | Module to resolve computer IP addresses | 140 | `-v` | `-v...` | Increase verbosity (`-v`, `-vv`, `-vvv`) | 141 | `-h` | `--help` | Print help | 142 | `-V` | `--version` | Print version | 143 144 --- 145 146 ## ๐ Basic Usage 147 148 ```bash 149 # Minimal: password auth, zip the output 150 rusthound-ce -d domain.local -u user@domain.local -p 'Password123' -o output/ -z 151 152 # Point at a specific DC by IP (skip DNS discovery) 153 rusthound-ce -d domain.local -u user@domain.local -p 'Password123' \ 154 -i 10.10.10.10 -o output/ -z 155 156 # Verbose (trace what LDAP queries run and why something is missing) 157 rusthound-ce -d domain.local -u user@domain.local -p 'Password123' \ 158 -o output/ -z -vv 159 ``` 160 161 Output is a set of `*_users.json`, `*_computers.json`, `*_groups.json`, `*_gpos.json`, `*_ous.json`, `*_domains.json`, `*_containers.json` files (plus ADCS/cert objects when reachable). With `-z` they are bundled into a timestamped zip ready for upload. 162 163 --- 164 165 ## ๐ Authentication Methods 166 167 ### Username + password 168 ```bash 169 rusthound-ce -d domain.local -u user@domain.local -p 'Password123' -o output/ -z 170 ``` 171 172 ### Pass-the-hash (NTLM) 173 ```bash 174 # NT hash only; leave the LM half empty 175 rusthound-ce -d domain.local -u user -H :2b576acbe6bcfda7294d6bd18041b8fe -o output/ -z 176 ``` 177 178 ### Kerberos (ccache) 179 ```bash 180 # 1) Obtain a TGT (impacket) and export the ccache 181 getTGT.py domain.local/user:'Password123' -dc-ip 10.10.10.10 182 export KRB5CCNAME=$PWD/user.ccache 183 184 # 2) Collect with -k; -f names the DC so the SPN resolves 185 rusthound-ce -d domain.local -k -f DC01.domain.local -o output/ -z 186 ``` 187 On a **domain-joined Windows** host you can just run `rusthound-ce -d domain.local -k -f DC01` to reuse the current logon session. 188 189 ### Client certificate (PKINIT / LDAPS mTLS) 190 ```bash 191 # PEM cert + key 192 rusthound-ce -d DOMAIN.LOCAL -f DC01.DOMAIN.LOCAL \ 193 --crt user.crt --key user.key --ldaps -o output/ -z 194 195 # PFX bundle 196 rusthound-ce -d DOMAIN.LOCAL -f DC01.DOMAIN.LOCAL \ 197 --pfx user.pfx --pfx-pass 'certpass' --ldaps -o output/ -z 198 ``` 199 Useful after an ADCS/Shadow-Credentials attack where you hold a certificate but no cleartext password. 200 201 --- 202 203 ## ๐๏ธ Collection Methods 204 205 ```bash 206 # All (default): LDAP + SMB + HTTP โ full session/local-group data 207 rusthound-ce -c All -d domain.local -u user@domain.local -p 'pass' -o output/ -z 208 209 # DCOnly: LDAP against the DC only โ no SMB/HTTP touch to member hosts 210 rusthound-ce -c DCOnly -d domain.local -u user@domain.local -p 'pass' -o output/ -z 211 ``` 212 213 - **All** โ LDAP objects plus SMB/HTTP calls to member computers for sessions and local-group membership. Louder, needs reachability to hosts, but yields richer attack paths. 214 - **DCOnly** โ talks only to the DC over LDAP. Quietest option: no direct contact with workstations/servers, so no per-host sessions or local admin data, but full objects, ACLs, trusts and GPOs. 215 216 ### Custom LDAP filter 217 ```bash 218 # Narrow the collection (e.g. one OU or object class) 219 rusthound-ce -d domain.local -u user@domain.local -p 'pass' \ 220 --ldap-filter '(objectClass=user)' -o output/ -z 221 ``` 222 223 --- 224 225 ## โก Performance & Reliability 226 227 ```bash 228 # Cache LDAP results to disk with a large buffer (big domains) 229 rusthound-ce -d domain.local -u user@domain.local -p 'pass' \ 230 -o output/ --cache --cache-buffer 10000 -z 231 232 # Resume a collection that was interrupted (flaky link / disconnect) 233 rusthound-ce -d domain.local -u user@domain.local -p 'pass' \ 234 -o output/ --cache --resume -z 235 ``` 236 `--cache` writes intermediate results so `--resume` can pick up where a dropped run left off. Raise `--cache-buffer` for very large directories to reduce disk churn. 237 238 --- 239 240 ## ๐ DNS & Host Resolution 241 242 ```bash 243 # Resolve computer IPs during collection 244 rusthound-ce -d domain.local -u user@domain.local -p 'pass' \ 245 --fqdn-resolver -o output/ -z 246 247 # Force TCP for DNS (UDP blocked/filtered) and use a specific resolver 248 rusthound-ce -d domain.local -u user@domain.local -p 'pass' \ 249 --fqdn-resolver --dns-tcp -n 10.10.10.10 -o output/ -z 250 ``` 251 `--fqdn-resolver` maps computer objects to IP addresses; combine with `--dns-tcp` when UDP/53 is filtered, and `-n` to point at the internal DNS server (usually the DC). 252 253 --- 254 255 ## โฐ Time Skew & Kerberos Gotchas 256 257 Kerberos rejects tickets when the clock differs from the DC by more than ~5 minutes (`KRB_AP_ERR_SKEW`). Sync or fake your clock: 258 259 ```bash 260 # Read DC time, then wrap the collector with faketime 261 sudo ntpdate 10.10.10.10 # if allowed 262 # or 263 faketime "$(date -u -d "$(net time -S 10.10.10.10)" '+%Y-%m-%d %H:%M:%S')" \ 264 rusthound-ce -d domain.local -k -f DC01.domain.local -o output/ -z 265 ``` 266 See the **faketime** note for the reliable one-liner pattern. 267 268 --- 269 270 ## ๐ฅ Ingesting into BloodHound CE 271 272 ```bash 273 # Output is already CE-schema JSON; -z gives one zip to upload 274 rusthound-ce -d domain.local -u user@domain.local -p 'pass' -o output/ -z 275 ``` 276 277 1. Open the BloodHound **CE** web UI. 278 2. Go to **Administration / File Ingest** (or drag-and-drop onto the graph). 279 3. Upload the `.zip` (or the individual `.json` files). 280 4. Wait for the ingest job to finish, then run built-in queries (Shortest Paths to Domain Admins, Kerberoastable users, etc.). 281 282 > [!tip] Automated upload 283 > You can push the JSON straight into CE with the `bloodhound-cli` / API or tools like `bhcli`, avoiding the web upload for repeatable pipelines. 284 285 --- 286 287 ## ๐ SharpHound / bloodhound-python Equivalents 288 289 | Goal | RustHound-CE | SharpHound (v2, CE) | bloodhound-ce-python | 290 |:-----|:-------------|:--------------------|:---------------------| 291 | Full collection, zipped | `-c All ... -z` | `-c All --zippassword ...` | `-c All --zip` | 292 | DC-only / quiet | `-c DCOnly` | `-c DCOnly` | `-c DCOnly` | 293 | Pass-the-hash | `-H :<nt>` | (via runas/pth) | `--hashes :<nt>` | 294 | Kerberos ccache | `-k -f DC01` | `--kerberos` | `-k` | 295 | Target DC | `-i <ip>` / `-f <fqdn>` | `--domaincontroller` | `-dc <fqdn> -ns <ip>` | 296 | LDAPS | `--ldaps` | `--secureldap` | `--use-ldaps` | 297 | Output dir | `-o <dir>` | `--outputdirectory` | `-op` / cwd | 298 299 RustHound-CE fills the same niche as `bloodhound-ce-python` (remote, Linux-friendly) but as a fast native binary rather than a Python tool. See both companion notes. 300 301 --- 302 303 ## ๐ ๏ธ Troubleshooting 304 305 | Symptom | Likely cause | Fix | 306 |:--------|:-------------|:----| 307 | `KRB_AP_ERR_SKEW` | Clock drift vs DC | Sync time or wrap with `faketime` | 308 | Empty / tiny output | Wrong domain or no LDAP reach | Verify `-d`, add `-i <DC IP>`, check port 389/636 | 309 | TLS / cert errors on `--ldaps` | Untrusted DC cert / wrong FQDN | Use correct `-f` FQDN; confirm CA trust | 310 | Missing sessions / local admins | Ran `DCOnly`, or hosts unreachable | Use `-c All` and ensure SMB/HTTP reachability | 311 | Hangs on large domains | No caching, big directory | Add `--cache --cache-buffer 10000` | 312 | Computer IPs missing | Resolver disabled | Add `--fqdn-resolver` (+ `--dns-tcp -n <DNS>`) | 313 | Auth fails with hash | LM half included | Use `-H :<nthash>` (empty LM) | 314 | "wrong schema" on upload | Legacy BloodHound server | Use a **CE** server, or a legacy collector instead | 315 316 Add `-v`, `-vv`, or `-vvv` to see the exact LDAP queries and where collection stalls. 317 318 --- 319 320 ## ๐ถ๏ธ OPSEC Notes 321 322 > **Context โ** Authorised engagements / lab use only. 323 324 - LDAP enumeration against a DC is **high-signal** to defenders (BloodHound-style query patterns are widely alerted on). Prefer `-c DCOnly` when you only need objects/ACLs and want to avoid touching member hosts. 325 - `-c All` reaches out to workstations/servers over SMB/HTTP for sessions and local groups โ noisier and leaves host-side artifacts. 326 - LDAPS (`--ldaps`) encrypts the query traffic but does not hide the *volume* or *pattern* of queries. 327 - Throttle / scope with `--ldap-filter` and target a single DC (`-i`/`-f`) to keep the footprint small. 328 - Certificate and Kerberos auth avoid sending a cleartext password over the wire; pair with proper ticket hygiene.