AD Attacks

BloodHound / SharpHound

BloodHound collection, import, and attack path analysis: bloodhound-python, SharpHound, critical Cypher queries, shortest-path to DA, ACL abuse chains, delegation paths, and how to read BloodHound output into actionable attacks.

BloodHound graphs AD relationships that are invisible in raw LDAP output — group memberships, ACL edges, session data, and delegation flags — then finds the shortest attack path to Domain Admin. Run collection first, then mark your owned nodes and follow the edges.

Collection

bloodhound-python (from Linux — no agent needed)

# Full collection (all data types)
bloodhound-python -d corp.local -u user -p 'password' -c All -ns DC_IP

# With hash (Pass-the-Hash)
bloodhound-python -d corp.local -u user --hashes :NTLM_HASH -c All -ns DC_IP

# Specific collection methods
bloodhound-python -d corp.local -u user -p 'password' \
  -c Group,LocalAdmin,Session,Trusts,ObjectProps,ACL -ns DC_IP

# Stealth — skip session enumeration (less noise)
bloodhound-python -d corp.local -u user -p 'password' -c Group,ObjectProps,ACL -ns DC_IP

# Output to directory
bloodhound-python -d corp.local -u user -p 'password' -c All -ns DC_IP -o /tmp/bh/

SharpHound (Windows — runs as current user)

# PowerShell import
Import-Module .\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All -OutputDirectory C:\Temp\

# Standalone EXE
.\SharpHound.exe -c All --outputdirectory C:\Temp\
.\SharpHound.exe -c All --zipfilename bh_data.zip

# Stealth options
.\SharpHound.exe -c Group,ObjectProps,ACL --NoSaveCache
.\SharpHound.exe -c All --throttle 1000 --jitter 20

# Target specific DC
.\SharpHound.exe -c All --domaincontroller DC_IP

NetExec LDAP collection

nxc ldap DC_IP -u user -p 'password' --bloodhound --collection All

Import into BloodHound

# Start Neo4j (BloodHound backend)
sudo neo4j start
# Default credentials: neo4j / neo4j (change on first login)

# BloodHound GUI — drag and drop the zip/JSON files into the UI
# Or use the Upload Data button in the top-right

# BloodHound CE (community edition) via Docker
docker run -d -p 8080:8080 -p 7474:7474 -p 7687:7687 specterops/bloodhound-ce

First Steps After Import

  1. Set owned nodes: right-click a node → Mark as Owned
  2. Set high-value targets: Workstations / Servers / DCs are auto-tagged
  3. Run “Find Shortest Paths to Domain Admins” from the Analysis menu
  4. Run “Find Principals with DCSync Rights” to see who can replicate
  5. Check the “Outbound Object Control” panel for your owned user

Essential Cypher Queries (Raw Queries tab or BloodHound GUI)

All paths from owned nodes to Domain Admins

MATCH p=shortestPath((n:User {owned:true})-[*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'}))
RETURN p

Find Kerberoastable users and their admin rights

MATCH (u:User {hasspn:true}) RETURN u.name, u.admincount ORDER BY u.admincount DESC

Find AS-REP roastable users

MATCH (u:User {dontreqpreauth:true}) RETURN u.name

Computers with unconstrained delegation (not DCs)

MATCH (c:Computer {unconstraineddelegation:true}) WHERE NOT c.name CONTAINS 'DC' RETURN c.name

Users with constrained delegation

MATCH (u:User) WHERE u.allowedtodelegate IS NOT NULL RETURN u.name, u.allowedtodelegate

Find all ACL paths from a user to Domain Admins

MATCH p=allShortestPaths((u:User {name:'JSMITH@CORP.LOCAL'})-[:GenericAll|GenericWrite|WriteOwner|WriteDacl|Owns|AddMember|ForceChangePassword*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'})) RETURN p

All objects with GenericAll over another object

MATCH (n)-[r:GenericAll]->(m) RETURN n.name, type(r), m.name LIMIT 50

Find local admin rights for a user across all computers

MATCH (u:User {name:'JSMITH@CORP.LOCAL'})-[:AdminTo]->(c:Computer) RETURN c.name

Find computers where domain users have local admin (high-risk)

MATCH (g:Group {name:'DOMAIN USERS@CORP.LOCAL'})-[:AdminTo]->(c:Computer) RETURN c.name

Groups with DCSync privileges

MATCH p=(n)-[:DCSync|GetChanges|GetChangesAll]->(d:Domain) RETURN n.name, type(relationships(p)[0])

Shortest path from owned computer to Domain Admin

MATCH p=shortestPath((c:Computer {owned:true})-[*1..]->(g:Group {name:'DOMAIN ADMINS@CORP.LOCAL'})) RETURN p

Reading BloodHound Edges

EdgeAttackTool
MemberOfGroup membership
AdminToLocal adminPsExec/WMI/evil-winrm
HasSessionUser logged in on hostPTH or token impersonation
GenericAllFull control — reset password, add member, write SPNPowerView
GenericWriteWrite specific attributes (SPN → Kerberoast, logon script)PowerView
WriteOwnerTake ownership → then WriteDACLPowerView
WriteDaclModify DACL → grant yourself GenericAllPowerView
OwnsSame as WriteOwnerPowerView
ForceChangePasswordChange password without knowing old onePowerView
AddMemberAdd user to groupPowerView
AllowedToDelegateConstrained/unconstrained delegationRubeus
AllowedToActRBCD — request tickets as any userRubeus
DCSyncReplicate domain hashessecretsdump/mimikatz
ReadLAPSPasswordRead local admin LAPS passwordPowerView/nxc
ReadGMSAPasswordRead gMSA managed passwordPowerView/nxc
CanRDPRemote Desktop accessxfreerdp/mstsc

Attack Workflow

1. Mark foothold users/computers as Owned
2. Run "Shortest Paths from Owned Principals"
3. Find the easiest edge:
   - MemberOf a group with AdminTo → PTH to host → dump LSASS → new creds → loop
   - GenericAll on user → ForceChangePassword → log in as them
   - WriteSPN → Kerberoast → crack hash → new creds
   - WriteDACL on domain obj → grant DCSync → dump all hashes
4. Execute the edge with PowerView/Rubeus/impacket
5. Mark new objects as Owned, re-run paths