GhostHound is a BloodHound OpenGraph extension for
Active Directory. SharpHound and every other AD collector skip CN=Deleted Objects: deleted
objects (tombstones) are invisible to standard BloodHound attack-path analysis, even though the AD
Recycle Bin and tombstone reanimation mechanisms can let a sufficiently-privileged principal
restore one — and take over whatever identity it represents. GhostHound enumerates tombstones over
LDAP with the SHOW_DELETED control, determines who can reanimate each one, and emits an OpenGraph
JSON payload plus a model.json extension definition so BloodHound CE v8+ can render this as a
first-class part of the graph.
Authorized use only. This is an offensive-security / red-team tool intended for authorized penetration tests and detection-lab research. Only run it against Active Directory environments you are explicitly authorized to test.
Administrators-equivalent rights (or an explicit delegation of read access toCN=Deleted Objects) on the target domain. Non-privileged accounts cannot see the container at all, regardless of which auth method is used — this is an AD-enforced restriction, not something GhostHound can work around.- Network reachability to a Domain Controller on LDAP (389) or LDAPS (636).
- BloodHound CE v8+ if you want to import the resulting graph (collection and JSON output work standalone without it).
ghosthound -d ghost.local --dc-ip 10.0.0.10 -u alice -o tombstones.jsonPassword resolution order: --password (avoid — visible via ps//proc/<pid>/cmdline and shell
history), then the LDAP_PASSWORD environment variable, then an interactive prompt if neither is
set.
By default GhostHound connects over LDAPS (636) with certificate verification on. Two flags exist for environments where that doesn't fit:
--disable-ldaps— fall back to cleartext LDAP (389). The bind password is sent in plaintext; avoid this against anything but an isolated lab.--insecure-tls— keep LDAPS (encrypted transport) but skip certificate verification, for self-signed/lab certificates that aren't in your trust store. Prefer this over--disable-ldapswhenever the DC's cert is the only problem.
--timeout-secs (default 30) bounds both the initial connection and every subsequent LDAP
operation, so an unreachable DC or a wrong --dc-ip fails within that window instead of hanging.
Run ghosthound --help for the full flag list.
GhostHound is built as a library-first workspace — see docs/adr/0001-language-rust-library-first.md
for the rationale:
bloodhound-opengraph: BloodHound OpenGraph JSON builder (the Rust counterpart to Python'sbhopengraph).ad-secdesc: permissively-licensed, from-scratch parser forntSecurityDescriptor/DACL/ACEs (seedocs/adr/0003-security-descriptor-parsing-strategy.mdfor why this isn't a dependency on the only existing Rust equivalent, which is GPL-3.0).ad-secdesc-oracle: internal, unpublished differential test harness comparingad-secdescagainst that GPL-3.0 crate as a black-box oracle — quarantined out of the default build and every published crate's dependency graph.ad-tombstone: LDAPSHOW_DELETEDenumeration, AD Recycle Bin state modeling, and reanimation-rights analysis.ghosthound: the CLI orchestrating the above.
- In BloodHound CE's OpenGraph Management page, upload
crates/ad-tombstone/model.jsononce to register theGhostHound_TombstoneUser/GhostHound_TombstoneComputer/GhostHound_TombstoneGroupnode kinds and theGhostHound_CanReanimate/GhostHound_WasMemberOf/GhostHound_SameAsrelationship kinds (all registered as traversable, so they participate in shortest-path queries). - Upload the JSON GhostHound produced (via the UI or the ingest API) as a normal OpenGraph data payload.
- Run
crates/ad-tombstone/bridge_shadow_nodes.cypherdirectly against Neo4j (BloodHound CE's own Cypher search bar is read-only and will reject it):GhostHound's edges to existing AD principals (Domain Admins, etc.) land on placeholder nodes rather than the real ones BloodHound already has — an OpenGraph ingest limitation, not a bug in this data; seedocker exec -i <graph-db-container> cypher-shell -u neo4j -p <password> < crates/ad-tombstone/bridge_shadow_nodes.cypher
docs/adr/0006-opengraph-cross-source-node-identity.md. This script bridges them so paths are actually traversable. Safe to re-run after every import. - Import the starter queries in
crates/ad-tombstone/queries.jsonand, optionally, runcrates/ad-tombstone/privilege_zones.cypheronce to tag tombstones under Tier Zero OUs as high-value — this also needscypher-shellrather than the search bar, for the same reason as step 3 (itsSETis an updating clause too).
Once bridged, the reanimation path renders as a normal traversable path — a tombstone that was a Domain Admins member before deletion, reachable by every principal with the Reanimate-Tombstones right, bridged into the real Domain Admins node:
This project prioritizes high-confidence security from day 1 (docs/adr/0005-supply-chain-openssf-posture.md):
cargo denyfor strict copyleft/GPL bans and vulnerability auditing.- OpenSSF Scorecard workflows.
cargo fuzzfor panic safety in parsing raw binary descriptors.- No
unsafein foundational libraries.
The docs/adr/ directory records the decisions behind this design (language choice, auth scope,
the ad-secdesc licensing constraint, the AD Recycle Bin data model, supply-chain posture), and
docs/research/tombstone-viability-findings.md has the underlying research.
