BloodHound ingestion + canonical Cypher queries for AD attack-path enumeration. Run after collector dumps zip; promotes findings into the knowledge graph.
61
73%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
Fix and improve this skill with Tessl
tessl review fix ./packages/decepticon/decepticon/skills/standard/ad/bloodhound-query/SKILL.md# Python collector (works from Linux attacker box)
bloodhound-python -u USER -p 'PASS' -d DOMAIN -c all --zip --dns-tcp \
-ns DC_IP -o /workspace/bh.zip
# Or SharpHound from a Windows beachhead
# Invoke-BloodHound -CollectionMethod All -ZipFileName bh.zipIf bloodhound-python errors on TLS, add -gc gc.domain.local for the
global catalog FQDN.
bh_ingest_zip("/workspace/bh.zip")This populates User / Computer / Group / GPO / OU nodes with attribute properties (hasspn, dontreqpreauth, enabled, admincount, sidhistory).
Run via bh_cypher("<query>") or post-process kg_query(kind=...):
| Goal | Cypher |
|---|---|
| Owned principals | MATCH (u) WHERE u.owned=true RETURN u.name |
| Shortest path to DA | MATCH p=shortestPath((u {owned:true})-[*1..]->(g:Group {name:'DOMAIN ADMINS@DOM'})) RETURN p |
| Kerberoastable users | MATCH (u:User {hasspn:true, enabled:true}) RETURN u.name,u.spns |
| AS-REP roastable | MATCH (u:User {dontreqpreauth:true, enabled:true}) RETURN u.name |
| DCSync candidates | `MATCH (n)-[:GetChanges |
| Unconstrained delegation | MATCH (c:Computer {unconstraineddelegation:true}) RETURN c.name |
| RBCD targets | MATCH (n)-[:AddAllowedToAct]->(c:Computer) RETURN n.name,c.name |
| GenericAll on user | MATCH (n)-[:GenericAll]->(u:User) WHERE NOT n=u RETURN n.name,u.name |
| ACL path to high-value | `MATCH p=shortestPath((u {owned:true})-[:GenericAll |
| Sessions on DC | MATCH (u:User)-[:HasSession]->(c:Computer) WHERE c.name CONTAINS 'DC' RETURN u.name,c.name |
| Computers w/ admin from owned | MATCH (u {owned:true})-[:AdminTo*1..2]->(c:Computer) RETURN c.name |
| GPO abuse | MATCH (n)-[:GpLink]->(:OU)-[:Contains*1..]->(c:Computer) WHERE n.name CONTAINS 'unsafe' RETURN n.name,c.name |
After ingest:
plan_attack_chains(promote=True)This walks the graph from owned → high-value and surfaces:
For each materialized path, add to KG:
kg_add_node(kind="attack_path", label="<owned-user> → <high-value>",
props={"hops":<n>, "edges":"<edge-types>", "severity":"critical"})
kg_add_edge(src=<attack_path>, dst=<crown_jewel>, kind="reaches", weight=1.0)| Symptom | Fix |
|---|---|
| LDAP bind error | Wrong creds or password expired — try -p '<empty>' for null bind |
| Sessions: 0 | RPC blocked — add --computerfile <list> to skip enum |
| ACL: 0 | Account lacks RIGHT_DS_READ_PROPERTY — try diff user |
| ZIP empty | Collector crashed mid-run — check --workers 1 -d <domain> |
| Path discovered | Severity |
|---|---|
| Owned → DA shortest path ≤ 3 hops | Critical (10.0) — engagement-ending |
| Owned → server admin | High (8.0) |
| GenericAll on high-value user | High (8.0) — single ACL = takeover |
| Kerberoastable + offline-crackable hash | Medium-High (6-8) — needs crack |
| Unconstrained delegation on non-DC | High (8.0) — TGT capture |
e34afba
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.