Building

Doing it Server-Side with CypherDog 4.0

Arrroooo… Bloodhound Crew!! Heard the news? CypherDog 4.0 is out and it’s full of new features…

Now a couple of you might be thinking “Hey there, wait a minute… didn’t CypherDog 3.0 come out not that long ago..??”, and I am happy to see some of you are paying attention…
Indeed, when Bloodhound 3 came out, I quickly updated CypherDog 2 to CypherDog 3 to be compatible with it.
But Bloodhound 3 is compatible with neo4j 3 and 4, however the neo4j REST API has been deprecated in neo4j 4 and CypherDog 3 relied on it.
Long story short, CypherDog 4.0 is a full rewrite compatible with the new neo4j 4 HTTP API, and since I was refactoring the whole thing, I added some cool new features to the tool.
The idea was to be able to do more with less keystrokes, and to do it server-side…
And so I made a meme.

In this post I will share some basic commands to get you started with the toolset, and I will highlight some of the new features I baked into it.

 

Retrieving Nodes

The Basic command to manipulate nodes is Get-BloodHoundNode and it’s alias Node

# Retrieve all nodes by type
Node User

# Retrieve node by name
Node User ALICE@COFFEE.CUP

# Retrieve multiple names
Node User ALICE@COFFEE.CUP,BOB@COFFEE.CUP

Here is what the output looks like


Retrieving user by name

Retrieving multiple users / Comparing props

Nodes can also be retrieved by properties

# Single Prop
Node User -Props @{enabled=$true}

# Multiple Props
Node User -Props @{enabled=$true;highvalue=$true}


Retrieving nodes by properties

but my favorite new feature has to be the -Where parameter.
You can pass a Cypher string to it… server-side filtering possibilities become endless…

# Where + Operator
Node User -Where "x.name STARTS WITH 'ALICE'"

# Where + Path condition
Node User -Where "(x)-[:MemberOf*1..]->(:Group {name:'DOMAIN ADMINS@COFFEE.CUP'})"


Node + Where + Operator


Node + Where + Path condition

And that’s not it for Cypher…
To further fine tune your queries, you can also input Cypher syntax after the -With / -Return / -OrderBy / -Limit parameters…

 

Retrieving Edges

If you want to visualize single-edge type relationships between objects, you can use the Get-BloodHoundEdge cmdlet (aka Edge).
Basic usage goes as follows (and everything should tab-complete):

Edge <SourceType> <EdgeType> <TargetType> [<SourceName>] [<TargetName>] [+OtherOptions...]

so you can do something like that… (* means ‘Any’)

Any user direct member of DA

Computers where Administrator is direct admin

and because you’re in PowerShell, you could use the Group-Object cmdlet and do something like that…


Count of sessions per user / user with most session

or what about that..?


Edge + Path Condition: User has session on computer where he is admin

and maybe even something like that…

Edge: Wheres everywhere!!

 

Retrieving Paths

Most of the time, you will want to be looking at chains of several edges. For this, you will be using the Get-BloodhoundPath cmdlet (aka Path). With this cmdlet you can build complex paths queries with minimal effort.

Here again, the -SourceWhere / -TargetWhere / -PathWhere parameters should allow you to retrieve just what you are looking for with efficient server-side filtering.
You can use -FilterEdge / -IncludeEdge / -ExcludeEdge / -MaxHop to generate desired edge constraints,
and  -With / -Return / -OrderBy / -Limit are also available to further fine-tuning your query…

Might be a bit too much for this blogpost, so i’ll share example for the basic usage, but make sure to check out all the switches when you play with it…

Basic construct goes as follow:

Path <SourceType> <TargetType> <SourceName> <TargetName> [+OtherOption...]

and a simple path query looks like that… (* means ‘Any’)


Basic path query: any user to DA

simply add the -Cypher to your command and pipe it into | Set-Clipboard to view matching graph in the BloodHound UI…

 

Calculating NodeWeight

Now if you followed my BloodHound adventures so far, you might remember something about NodeWeight (from here).
If that’s the case, you might be happy to hear that there is now a Get-BloodHoundPathNodeWeight cmdlet (aka NodeWeight)
You can simply pipe any CypherDog Path command into it, to get the weight of all the nodes on the resulting graph.


NodeWeight Calculation

 

Moar Stuff…

As  in previous versions, all cmdlets have a -Cypher switch to output the resulting cypher query without sending it to the server.
This is a great way to learn some Cypher syntax as you go. Make sure to check it out…
If you are already a Cypher ninja and simply want to send some advanced query of yours to the server, you can use Invoke-Neo4jCypher cmdlet (aka cypher or neo) followed by your cypher query to do just that…
(and never want to go back to the neo4j browser experience imo)

Whatever Cypher query you want…

Did I also mention I added authentication? Loads of little utilities for DIY and further tweaking??
And of course, there are also Cmdlets to Create / Modify / Delete stuff if you want to.
All I will say is be careful with these, and don’t blame me if you break something…
Maybe backup your DB beforehand… just in case you “didn’t want to delete ALL that…”

Anyways… enough for today I guess.
I hope you will enjoy this new version of the tool…
Code can be found here.
Hit me on BloodHound Slack if you have any questions, issues or feedback.

Hack the Planet.

Catch you later…

@SadProcessor