Hi there,
SadProcessor here, happy to be back on the Insinuator to share with you some of my latest BloodHound adventures and experiments…
TL;DR Well too bad for you…

Before diving into a bit of code and some BloodHound data manipulation,
I would like to thank the BruCon Crew for having me over last week for
BruCON0x0B.
I had the pleasure of delivering a 4h BloodHound & Cypher workshop in the
lovely city of Gent [in a fantastic training room], and I am pleased with the
interaction & feedback I had with the attendees.
I was also very happy to see almost as many Blues as Reds in the room [as well
as regular security folks!!], all together having a play with BloodHound &
Cypher.

BloodHound was originally designed out of a red team’s need for an AD
reconnaissance tool allowing to quickly find attack paths to desired targets
during engagements. And it does a great job at it.
But putting BloodHound in the hands of Blue Teams and Security Consultants can
help greatly reduce the attack surface before the Red Team comes into play.
This will only add value to your red team exercises.

If your car has really old tires, you don’t really need a crash test dummy to
come and confirm you wont survive the crash…
**
I believe BloodHound is great tool for AD auditing in general**, and in this
post I will share a simple technique that I have successfully used on AD
Hardening projects in order to quickly identify sensitive nodes in the
BloodHound graph, domain-wide and at scale… and this without even looking at the
graph.
Before getting into some PowerShell, I will quickly explain what we are going to
do with a simple example.
Let’s say we have the following pseudo-graph in BloodHound:

What we are looking at is actually an overlapping equivalent of the following:

Once we look at it this way, we can easily count how many times a node appears on the total number of path to a specified target…

Doing so gives us a kind of weight for each node on the graph, and we can calculate which node have the most impact on the total number of paths to a specific target.
To achieve this type of data manipulation in Bloodhound “without looking”, you can use the REST API and a bit of Cypher wrapped in the scripting language of your choosing [I chose PowerShell so it runs everywhere… just like BloodHound].
First we will authorize unauthenticated requests to the REST API by uncommenting the following line in neo4j.conf

Note: This other setting being commented restricts it to localhost only [and this is what we want].

Please make sure to consider all security implications of having an open
BloodHound database on your network before uncommenting this line.
If this is not for your lab or for localhost only, make sure to implement some
kind of authentication,
as you probably don’t want this to be an open-bar…
Once this is done, we can send Cypher to the REST API with the following PowerShell Code.

The REST API returns JSON, so the PowerShell Invoke-RestMethod
Cmdlet [aka irm] is a perfect tool for the job… It will automatically convert
it to a nice object for you, and you can simply dot properties to expand objects
and manipulate them further
[Instructions for calls in Bash or Python can be found
here if you
prefer [but c’mon bruh…dat PoSh…]]
Using this snippet, I have written a small Cmdlet called Invoke-Cypher that you can use to send any Cypher query to neo4j REST API [and build all kinds of automation around it].

An example of requesting a specific Node would look something like this:

The Node type [aka Label] is in $Node.metadata, and all Node properties are in $Node.data

And you can of course change the Cypher query to anything you like… So let’s get back to some BloodHound…

In the following example we are requesting shortest User paths to DA [any-to-one].
We can do so by sending the following query:

[Path from any user to a specific group with any types of edges and with no max length]
and this is what [one of] the returned Path Object looks like.

Notice how some data is returned in the form of URLs.
More calls [irm] to the REST API are then necessary to request these
objects.
[but we will leave it for now… more on this later]
In our example, the returned result was a collection 33 objects, so we have 33 unique users with a path to our target

Same as on the overlapping BloodHound Graph [count if you like…]

The interesting bit for our experiment is the nodes property of these
objects returned.
When we expand this with $PathCollection.Nodes, PowerShell gives us a list of
all the nodes on all the paths.

Nodes are repeated in the list the number of times that they are present in total [like on the ‘non-overlaping’ graph], and using the Group-Object PowerShell Cmdlet we can very simply count them and get this weight we wanted to calculate…

If you followed carefully so far, you might have noticed that node with a count
of 33 already…
And you might have guessed this is our target node [here the DA group], since
that’s the one that is on all the 33 path we collected.
[472 is the neo4j DB internal object ID. You can also find it in the metadata
of the node object itself]
We can now make those calls to the REST API to get the node info, but we already have the weight we were looking for, and we will have to make less calls to get he rest of the info since each node will only be called once [I had to learn this the hard way when testing this in very large envs…]

Anyways, and getting back to that cool active directory auditing technic I
mentioned,
I have put all this into a little set of Cmdlet called WatchDog [just a POC
for now and still a work in progress]
I have had good results while testing this at customers, but the scale of the AD
environment can however be an issue for my code, as the powerShell Group-Object
can become a bottleneck for performance when dealing with a lot of paths …
So I added a limit [in Cypher] to the first 10000 shortest paths by default
[which should be way enough in most cases] but you can modify it as a Cmdlet
parameter if you need.
The first Cmdlet is Invoke-DataDog [a wrapper around Invoke-Cypher].
Function sends several Cypher queries to BH and formats returned result.
You give it a Group name, and it will do the number crunching for you.

The NodeWeight Property of the result object holds Distance, Weight, and Impact [pct of ttl weight] for each node, as well as node type [label].
The second Cmdlet is Invoke-WatchDog [a wrapper around Invoke-DataDog].
You give it a domain name, and it will look for a list of known DA equiv or
sensitive groups [RegEx on SID],
it will do the DataDog thing for you, and output an object per group, holding
all the data we need for further investigation.

There is finally an Invoke-ReportDog Cmdlet that will generate a brief
human-readable summary of the extracted data.
You can simply pipe DataDog or WatchDog output into it and it will create a mini
text report for further analysis and deeper investigation [with CypherDog for
example…].

A ‘Total Impact‘ is calculated at the end of the report [there’s also a TotalImpact Cmdlet you can pipe Watchdog output into, but I can’t explain everything here… check it out]
This toolset is just a POC, I have tried to optimize performance but I’m
sure better can be achieved.
The technic used is of course not solid steel, but it is a cool way to interact
with the BloodHound DB, identify key nodes on the path to sensitive groups, and
get some global AD metrics out of it at scale.
I hope some of you will find this useful and want to dig deeper into BloodHound & Automation and this also for usage out of the pure Red Team context…
If you are interested in Active Directory Security in general [and are a German
speaker], join us at the
ERNW-Insight AD Summit
on the 19Nov. in Heidelberg for a full day of AD goodness…
[And don’t forget Troopers is also coming fast… we
plan to have an amazing AD track there too… and Rachelle & the Crew are already
working hard at making it the best year ever… Be there.]
That’s all I had to share for today…
Thanks for reading…
Code for the WatchDog Cmdlets can be found
here.
[Material for the Hands-On BloodHound Workshop can be found
there if you like]
Catch me on BloodHound Slack if you have any questions or remarks.

Enjoy the weekend, and Make the world a Safer Place…
Cheers.