notes 2026-09-01 · 6 min read

BloodHound Beyond Pretty Graphs: Validating Edges

Using BloodHound past the shortest path: collection quality, reading an edge before running anything, session volatility and Cypher queries.

BloodHound Beyond Pretty Graphs: Validating Edges

BloodHound becomes useful to an attacker when a point on the graph stops being an interesting relationship and becomes a validated sequence of control.

A lot of people use the tool as a screenshot generator.

Open Shortest Paths to Domain Admins.

See a red line.

Take a screenshot.

The real work starts afterward.

Every edge needs to represent an action that is possible in the live environment.

The examples below assume a lab or an authorized penetration test.

Graph versus validated path

BloodHound models relationships, not magical exploits

A user belongs to a group.

A group has an ACL over a computer.

A computer has an administrator session.

An account can modify another user.

A service account has an SPN.

A certificate template allows enrollment.

Each fact becomes a node, edge, or property.

The value appears when those relationships connect.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
gabriel
   |
   | GenericAll
   v
svc_deploy
   |
   | MemberOf
   v
Server Admins
   |
   | AdminTo
   v
APP01

The graph describes a candidate path.

Each step still needs proof.

Collection quality defines analysis quality

BloodHound cannot draw a relationship the collector never saw.

Incomplete collection creates an incomplete graph.

Sessions are temporary.

ACLs change.

SPNs change.

Hosts go offline.

AD CS may require additional collection depending on collector and version.

Before concluding that no path exists, I inspect what was collected and when.

A missing edge does not prove a missing relationship.

Shortest path does not mean best path

The mathematically shortest path may be operationally poor.

Consider two options.

Path A has three edges and requires a destructive technique on a critical server.

Path B has five edges and uses reversible ACL and group changes.

During a pentest, Path B may be the better choice.

An edge may also depend on a privileged session that disappeared after collection.

Shortest paths help prioritize.

The final path depends on reliability, impact, noise, and test safety.

Read the edge before executing anything

Open the relationship.

Read the abuse information.

Understand which permission creates the edge.

Then validate manually.

If BloodHound shows GenericWrite, identify the attribute that needs to be modified.

If it shows AddMember, confirm the group ACL.

If it shows AdminTo, verify what grants administrative access.

If it shows delegation, confirm SPNs, flags, and principals.

A good tool reduces reasoning time.

It does not replace reasoning.

Every edge needs validation

Identity context changes the path

You may know the password for gabriel.

You may also possess a TGT for svc_backup.

You may control a machine account.

Those identities are not equivalent.

BloodHound becomes more useful when you mark principals you actually control.

Then ask:

1
Which paths leave any principal I own?

That is more useful than focusing only on the initial user.

High Value Targets need context

Domain Admins is obvious.

The real objective of a pentest may be different.

Payment server.

CA.

SCCM.

Backup.

Hypervisor.

GitLab.

Azure Connect.

A custom Tier 0 service.

Marking relevant targets reveals paths that a preset focused on Domain Admin never shows.

In a real network, controlling backup infrastructure may matter as much as controlling a default group.

ACL paths are often the most interesting

GenericAll.

GenericWrite.

WriteDACL.

WriteOwner.

AddMember.

Object-specific rights.

Those relationships reveal privilege that group membership does not show.

An ordinary account may hold indirect control over a sensitive object.

This appears frequently in older environments with years of accumulated delegation.

Sessions are powerful and volatile

A session-related edge says that an identity was observed on a host.

That can change minutes later.

If an administrator was logged into APP01 during collection, the path may depend on that session still existing.

Treat sessions as temporal hypotheses.

Reconfirm them before making an operational decision.

Owned state and tags help manage the graph

Update the graph during testing.

Mark compromised accounts.

Mark hosts where you have administrative access.

Record validated paths.

This turns BloodHound into an operational workspace.

Without that state, the tester keeps recalculating where access has already been gained.

The graph should track the current state of the assessment.

Cypher enables better questions

Built-in queries help at first.

Cypher allows specific questions.

Conceptual example:

1
2
3
4
MATCH p=shortestPath(
  (u:User {name:'GABRIEL@LAB.LOCAL'})-[*1..]->(c:Computer)
)
RETURN p

In large environments, I prefer limiting edge types, depth, and target.

Overly broad queries create noise and unnecessary cost.

The question needs to be technical.

Which computers can I control through ACL relationships within three hops?

Which owned principals reach certificate templates?

Which paths reach the backup tier?

Those questions produce actionable information.

A beautiful path can fail on one operational detail

RBCD needs an appropriate principal and write access to the resource.

Shadow Credentials depends on PKINIT.

Kerberoasting depends on an SPN account and the strength of its credential.

AD CS depends on templates, mapping, and CA behavior.

NTLM Relay depends on target protections.

BloodHound shows necessary relationships.

It may not model every external prerequisite.

Manual validation remains mandatory.

I treat each edge as a contract

For every edge, I write four things.

Which principal I control.

Which right it has.

Which concrete action proves that right.

Which new state I gain afterward.

Example:

1
2
3
4
Principal: gabriel
Right: AddMember over Server Admins
Action: add gabriel to the group
New state: gabriel inherits administrative access to APP01

The graph has now become a reproducible plan.

From graph to attack plan

Cleanup can use the graph too

If you changed a group or ACL, record it. Do the same for passwords and delegation settings.

Revert those changes after validation.

Recalculate the path.

If a node remains marked as owned only because of a temporary change, restore the operational view as well.

This habit prevents pentest artifacts from remaining in the domain.

Defenders benefit from the same model

The graph reveals relationships that traditional group audits miss.

Defensive teams can search for paths starting from broad populations.

They can monitor ACL changes that create new paths.

They can identify principals with excessive transitive control.

The goal does not need to be zero paths.

Some relationships exist for operational reasons.

Reduce unnecessary paths and protect the unavoidable ones.

The difference between basic and useful BloodHound work

Basic BloodHound usage asks:

1
Is there a path?

Useful BloodHound work asks:

1
2
3
4
5
Does this path work today?
Which edge is most reliable?
What is the smallest action that proves control?
Which change do I need to revert?
Which alternate path exists if this edge fails?

That second set of questions turns the graph into a penetration test.

References

SpecterOps, BloodHound documentation.

SpecterOps, BloodHound Community Edition.

Microsoft Learn, Active Directory access control.

This post is licensed under CC BY 4.0 by the author.