Aug 6 2024 | sadprocessor

BloodHound Operator — Dog Whispering Reloaded

Share

BloodHound Operator — Dog Whispering Reloaded

It’s summer 2024 and we are back! Actually, we are SO back, so I decided that this required a little blog post.

If you like BloodHound & PowerShell, and if you want to automate all the BloodHound things, this post is written for you. In the last part, I’ll be sharing a new tool for all your Dog Whispering needs; but before that, a little intro…

TL;DR: Code is here.

Back in the BloodHound “Legacy” days, I wrote some PowerShell tooling to make my life easy and automate various tasks around BloodHound. When the new BloodHound came out, most of these tools were made obsolete.
At first, I thought about going into a deep depression, but then I realized it would be a great opportunity to write a better tool, and so I did (and joined the SpecterOps crew while I was at it!).

This post introduces this new PowerShell module and contains instructions on how to get started.

In this post:

  • Differences between the old and new BloodHound
  • Intro to the new BloodHound REST API
  • How to authenticate to the BloodHound API (with PowerShell)
  • Getting started with the BloodHound Operator module

Old BloodHound vs New BloodHound

In the old BloodHound (a.k.a. Legacy), the application was a single page electron app build on top of a neo4j graph database.

Old BloodHound / CypherDog

Interacting with Legacy BloodHound via the command-line was done by sending cypher queries directly to the neo4j database (and this is what the old CypherDog tool was doing).

Although this neo4j cypher query endpoint covered a lot of possible use cases for automation, we were kind of limited to just that. No other BloodHound application features were accessible.

For example, you had to be there to drag the the zip in the UI in order to import data, which has been the main show stopper for my dreams of fully automated BloodHound Collect-Ingest-Query-Analyze cycles when working with legacy.

But that was before…

The new BloodHound is a full Golang rewrite of the application and is built quite differently. The application is now containerized and composed of three images: BloodHound, neo4j and PostgreSQL.

New BloodHound / BloodHound Operator

Not only does this allow for much easier install and updates (raise your hand if you remember the pain of finding the proper jdk…), but the addition of the new database allows for some solid application features; turning the dog into a beast:

  • Multi-user access
  • Granular user roles & permissions
  • SAML SSO / MFA
  • Secure API auth
  • and more…

Last but not least, the new BloodHound is build around it’s own REST API: exactly what we need for automation. In the next part of this post, we’ll have a quick look at how it works.

Note: Accessing neo4j directly is still possible in BHCE, but it is no longer the recommended method as neo4j will be deprecated in a near future. Tooling built to interact with BHCE via neo4j will become obsolete.

BloodHound REST API

API Specs

The new BloodHound is build around it’s REST API. Request made via the UI are translated into REST API calls to query the databases. A list of available API endpoints can be found in the BloodHound UI under Setting Icon/API Explorer.

Below a full list of endpoint & methods available at the time of writing this post:

Method Route                                                                     Summary
------ ----- -------
get /api/v2/accept-eula Accept EULA
get /api/v2/ad-domains/{domain_id}/data-quality-stats Time series list of data qu…
get /api/v2/aiacas/{object_id} Get aiaca entity info
get /api/v2/aiacas/{object_id}/controllers List aiaca controllers
get /api/v2/asset-groups List all asset isolation gr…
post /api/v2/asset-groups Create an asset group
delete /api/v2/asset-groups/{asset_group_id} Delete an asset group
get /api/v2/asset-groups/{asset_group_id} Retrieve asset group by ID
put /api/v2/asset-groups/{asset_group_id} Update an asset group
get /api/v2/asset-groups/{asset_group_id}/collections Returns asset group collect…
get /api/v2/asset-groups/{asset_group_id}/combo-node Get the combo tree for an a…
get /api/v2/asset-groups/{asset_group_id}/custom-selectors Get asset group custom memb…
get /api/v2/asset-groups/{asset_group_id}/members List all asset isolation gr…
get /api/v2/asset-groups/{asset_group_id}/members/counts List counts of members of a…
post /api/v2/asset-groups/{asset_group_id}/selectors Update asset group selectors
put /api/v2/asset-groups/{asset_group_id}/selectors Update asset group selectors
delete /api/v2/asset-groups/{asset_group_id}/selectors/{asset_group_selector_id} Delete an asset group selec…
get /api/v2/attack-path-types List all attack path types
put /api/v2/attack-paths Starts generating attack pa…
put /api/v2/attack-paths/{attack_path_id}/acceptance Marks an attack path as acc…
get /api/v2/audit Get audit logs
get /api/v2/available-domains Get available domains
get /api/v2/azure-tenants/{tenant_id}/data-quality-stats Time series list of data qu…
get /api/v2/azure/{entity_type} Get Azure Entity
get /api/v2/base/{object_id} Get entity info
get /api/v2/base/{object_id}/controllables List control
get /api/v2/bloodhound-users List Users
post /api/v2/bloodhound-users Create a New User
delete /api/v2/bloodhound-users/{user_id} Delete a User
get /api/v2/bloodhound-users/{user_id} Lookup User
patch /api/v2/bloodhound-users/{user_id} Update a User
delete /api/v2/bloodhound-users/{user_id}/mfa Disenrolls user from multi-…
post /api/v2/bloodhound-users/{user_id}/mfa Enrolls user in MFA
get /api/v2/bloodhound-users/{user_id}/mfa-activation Returns MFA activation stat…
post /api/v2/bloodhound-users/{user_id}/mfa-activation Activates MFA for an enroll…
put /api/v2/bloodhound-users/{user_id}/secret Create or Set User Secret
delete /api/v2/bloodhound-users/{user_id}/secret Expire User Secret
get /api/v2/certtemplates/{object_id} Get certtemplate entity info
get /api/v2/certtemplates/{object_id}/controllers List certtemplate controlle…
get /api/v2/clients List Clients
post /api/v2/clients Create Client
delete /api/v2/clients/{client_id} Delete Client
get /api/v2/clients/{client_id} Retrieve Client
put /api/v2/clients/{client_id} Update Client
get /api/v2/clients/{client_id}/completed-jobs Get all completed jobs for …
get /api/v2/clients/{client_id}/completed-tasks Get all completed tasks for…
post /api/v2/clients/{client_id}/jobs Creates a scheduled job
get /api/v2/clients/{client_id}/tasks Creates a scheduled job
put /api/v2/clients/{client_id}/token Regenerate the authenticati…
post /api/v2/clients/error Client Error
put /api/v2/clients/update Update Client Values
get /api/v2/collectors/{collector_type} Get collector manifest
get /api/v2/collectors/{collector_type}/{version_tag} Get collector download by v…
get /api/v2/collectors/{collector_type}/{version_tag}/checksum Get collector checksum by v…
get /api/v2/completeness Get database completeness s…
get /api/v2/computers/{object_id} Get computer entity info
get /api/v2/computers/{object_id}/admin-rights List computer admin rights
get /api/v2/computers/{object_id}/admin-users List computer admins
get /api/v2/computers/{object_id}/constrained-delegation-rights List computer constrained d…
get /api/v2/computers/{object_id}/constrained-users List computer constrained u…
get /api/v2/computers/{object_id}/controllables List computer control
get /api/v2/computers/{object_id}/controllers List computer controllers
get /api/v2/computers/{object_id}/dcom-rights List computer DCOM rights
get /api/v2/computers/{object_id}/dcom-users List computer DCOM users
get /api/v2/computers/{object_id}/group-membership List computer group members…
get /api/v2/computers/{object_id}/ps-remote-rights List computer PSRemote righ…
get /api/v2/computers/{object_id}/ps-remote-users List computer PSRemote users
get /api/v2/computers/{object_id}/rdp-rights List computer RDP rights
get /api/v2/computers/{object_id}/rdp-users List computer RDPUsers
get /api/v2/computers/{object_id}/sessions List computer sessions
get /api/v2/computers/{object_id}/sql-admins List computer SQL Admins
get /api/v2/config List application configurat…
put /api/v2/config Write application configura…
get /api/v2/containers/{object_id} Get container entity info
get /api/v2/containers/{object_id}/controllers List container controllers
get /api/v2/datapipe/status Get datapipe status
get /api/v2/domains/{domain_id}/attack-path-findings Export attack path findings
get /api/v2/domains/{domain_id}/available-types List available attack paths
get /api/v2/domains/{domain_id}/details Get data for an attack path
get /api/v2/domains/{domain_id}/sparkline List attack path sparkline …
get /api/v2/domains/{object_id} Get domain entity info
patch /api/v2/domains/{object_id} Update the Domain entity
get /api/v2/domains/{object_id}/computers List domain computers
get /api/v2/domains/{object_id}/controllers List domain controllers
get /api/v2/domains/{object_id}/dc-syncers List domain DCSyncers
get /api/v2/domains/{object_id}/foreign-admins List domain foreign admins
get /api/v2/domains/{object_id}/foreign-gpo-controllers List domain foreign GPO con…
get /api/v2/domains/{object_id}/foreign-groups List domain foreign groups
get /api/v2/domains/{object_id}/foreign-users List domain foreign users
get /api/v2/domains/{object_id}/gpos List domain GPOs
get /api/v2/domains/{object_id}/groups List domain groups
get /api/v2/domains/{object_id}/inbound-trusts List domain inbound trusts
get /api/v2/domains/{object_id}/linked-gpos List domain linked GPOs
get /api/v2/domains/{object_id}/ous List domain OUs
get /api/v2/domains/{object_id}/outbound-trusts List domain outbound trusts
get /api/v2/domains/{object_id}/users List domain users
get /api/v2/enterprisecas/{object_id} Get enterpriseca entity info
get /api/v2/enterprisecas/{object_id}/controllers List enterpriseca controlle…
get /api/v2/events List Events
post /api/v2/events Create Event
put /api/v2/events/{event_id} Update Event
delete /api/v2/events/{event_id} Delete Event
get /api/v2/events/{event_id} Get Event
get /api/v2/features List feature flags
put /api/v2/features/{feature_id}/toggle Toggle a feature flag's ena…
get /api/v2/file-upload List File Upload Jobs
post /api/v2/file-upload/{file_upload_id} Upload File To Job
post /api/v2/file-upload/{file_upload_id}/end End File Upload Job
get /api/v2/file-upload/accepted-types Get accepted file types for…
post /api/v2/file-upload/start Create File Upload Job
get /api/v2/gpos/{object_id} Get gpo entity info
get /api/v2/gpos/{object_id}/computers List gpo affected computers
get /api/v2/gpos/{object_id}/containers List gpo affected OUs
get /api/v2/gpos/{object_id}/controllers List gpo controllers
get /api/v2/gpos/{object_id}/ous List gpo affected computers
get /api/v2/gpos/{object_id}/tier-zero List gpo affected computers
get /api/v2/gpos/{object_id}/users List gpo affected users
get /api/v2/graph-search Get search result
post /api/v2/graphs/cypher Runs a manual cypher query …
get /api/v2/graphs/edge-composition
get /api/v2/graphs/shortest-path Get the shortest path graph
get /api/v2/groups/{object_id} Get group entity info
get /api/v2/groups/{object_id}/admin-rights List group admin rights
get /api/v2/groups/{object_id}/controllables List group control
get /api/v2/groups/{object_id}/controllers List group direct controlle…
get /api/v2/groups/{object_id}/dcom-rights List group DCOM rights
get /api/v2/groups/{object_id}/members List group members
get /api/v2/groups/{object_id}/memberships List group membership
get /api/v2/groups/{object_id}/ps-remote-rights List group PSRemote rights
get /api/v2/groups/{object_id}/rdp-rights List group RDP rights
get /api/v2/groups/{object_id}/sessions List group sessions
post /api/v2/ingest Endpoint for data ingestion
get /api/v2/issuancepolicies/{object_id} Get issuance policy entity …
get /api/v2/issuancepolicies/{object_id}/controllers List issuance policy direct…
get /api/v2/issuancepolicies/{object_id}/linkedtemplates List issuance policy direct…
get /api/v2/jobs Get Jobs
get /api/v2/jobs/{job_id} Get Job
put /api/v2/jobs/{job_id}/cancel Cancels a scheduled job
get /api/v2/jobs/{job_id}/log Get Job Log File
get /api/v2/jobs/available Get Next Jobs
post /api/v2/jobs/end Notifies the API of a job e…
get /api/v2/jobs/finished Get Finished Jobs
post /api/v2/jobs/start Notifies the API of a job s…
post /api/v2/login Login to BloodHound
post /api/v2/logout Logout of BloodHound
get /api/v2/meta-nodes/{domain_id} Get latest tier zero combo …
get /api/v2/meta-trees/{domain_id} Get the graph for meta tree
get /api/v2/meta/{object_id} Get meta entity info
get /api/v2/ntauthstores/{object_id} Get ntauthstore entity info
get /api/v2/ntauthstores/{object_id}/controllers List ntauthstore controllers
get /api/v2/ous/{object_id} Get ou entity info
get /api/v2/ous/{object_id}/computers List OU computers
get /api/v2/ous/{object_id}/gpos List ou GPOs
get /api/v2/ous/{object_id}/groups List OU groups
get /api/v2/ous/{object_id}/users List ou users
get /api/v2/pathfinding Get pathfinding result
get /api/v2/permissions List Permissions
get /api/v2/permissions/{permission_id} Get Permission
get /api/v2/platform/{platform_id}/data-quality-stats Time series list of aggrega…
get /api/v2/posture-stats Get Posture Statistics
get /api/v2/roles List Roles
get /api/v2/roles/{role_id} Get Role
get /api/v2/rootcas/{object_id} Get rootca entity info
get /api/v2/rootcas/{object_id}/controllers List rootca controllers
get /api/v2/saml List SAML Providers
delete /api/v2/saml/{provider_id} Delete a SAML Provider
get /api/v2/saml/{provider_id} Get SAML Provider
post /api/v2/saml/providers Create a New SAML Provider …
get /api/v2/saved-queries Get all saved queries for t…
post /api/v2/saved-queries Create a User saved query
delete /api/v2/saved-queries/{saved_query_id} Delete a Saved query by its…
get /api/v2/search Get api
get /api/v2/self Lookup Self
get /api/v2/swagger/doc.json
get /api/v2/tasks Get Tasks
get /api/v2/tasks/{task_id} Get Job
put /api/v2/tasks/{task_id}/cancel Cancels a scheduled job
get /api/v2/tasks/{task_id}/log Get Job Log File
get /api/v2/tasks/available Get Next Tasks
post /api/v2/tasks/end Notifies the API of a job e…
get /api/v2/tasks/finished Get Finished Tasks
post /api/v2/tasks/start Notifies the API of a job s…
get /api/v2/tokens List Auth Tokens
post /api/v2/tokens Create Token for User
delete /api/v2/tokens/{token_id} Delete a User Token
get /api/v2/users/{object_id} Get user entity info
get /api/v2/users/{object_id}/admin-rights List user admin rights
get /api/v2/users/{object_id}/constrained-delegation-rights List user constrained deleg…
get /api/v2/users/{object_id}/controllables List user control
get /api/v2/users/{object_id}/controllers Get user controllers
get /api/v2/users/{object_id}/dcom-rights List user DCOM rights
get /api/v2/users/{object_id}/memberships List user group membership
get /api/v2/users/{object_id}/ps-remote-rights List user PSRemote rights
get /api/v2/users/{object_id}/rdp-rights List user RDP rights
get /api/v2/users/{object_id}/sessions List user sessions
get /api/v2/users/{object_id}/sql-admin-rights List user SQL admin rights
get /api/version Returns the supported API v…
post api/v2/clear-database Wipes your Bloodhound data …
get api/v2/jobs/current Get client job status
get api/v2/saml/sso Get all SAML sign on endpoi…
get api/v2/tasks/current Get client job status

TIP: You can also use your browser’s development tools to observe what exact calls are being made when clicking in the UI.

API Authentication

Now that we know what we can ask, the next question is how do we ask? When talking to the BloodHound REST API, all requests must be signed using a per-user token id and token key.

Creating the initial API token is done via the UI:

  • Click the Setting Icon and select Administration
  • Got to Manage Users and click on the drop down menu for the selected user.
  • Select Generate / Revoke API token and click on Create Token
  • Enter a token name and hit Save to display the created token:
Example token generation

Note: This token_id/token_key will only be displayed once. Make sure to take note of it and store it in a safe place.

The steps for the signature are as follows:

  • Take the operation (method+route) as bytes, and HMAC it with the token_key as bytes…
  • Take the previous output, and HMAC that with the 13 first chars of an RFC3339 timestamp as bytes…
  • Take the previous output, and HMAC that with the body as bytes…
  • Base64 that final output, and supply it as headers along with the timestamp and token_id .

Note: Your token_key is what proves you are who you say you are. Keep it private. Use a key vault. Do not expose it in scripts.

Ok, so what about PowerShell?

Below an example of what the signature process could look like in PowerShell:
(You can check here if you are looking for a Python example)

# Signature
$Timestamp = [Datetime]::utcnow.tostring('o')
$KeyByte = [Text.Encoding]::UTF8.GetBytes($TokenKey)
$OpByte = [Text.Encoding]::UTF8.GetBytes("$Method/$URI")
$DateByte = [Text.Encoding]::UTF8.GetBytes(-join $Timestamp[0..12])
$BodyByte = [Text.Encoding]::UTF8.GetBytes("$Body")
$HMAC = [Security.Cryptography.HMACSHA256]::new($KeyByte).ComputeHash($OpByte)
$HMAC = [Security.Cryptography.HMACSHA256]::new($HMAC).ComputeHash($DateByte)
$HMAC = [Security.Cryptography.HMACSHA256]::new($HMAC).ComputeHash($BodyByte)
$Sign = [Convert]::ToBase64String($HMAC)

# Headers
$Headers = @{
Authorization = "BHESignature $TokenID"
Signature = $Sign
RequestDate = $Timestamp
}

And that’s about as complicated as it gets. We are ready to start dog whispering again!

Now that we know how it’s done, and after a bit of a long intro (sorry!), let’s finally have a look at this new tool…

BloodHound Operator

BloodHound Operator is a new PowerShell module to interact with the BloodHound REST API. It is written in PowerShell and runs on Windows, Linux or MacOS (with PowerShell 7 installed).

Code can be found here.

  • This module is compatible with BloodHound Enterprise and BloodHound Community edition
  • The code is shared as a PoC and subject to changes
  • This is not an officially supported SpecterOps tool (but you can ping me on the BloodHound Slack if you have any questions)

The module contains cmdlets to interact with most API endpoints and is compatible with BHE and BHCE. All cmdlet follow the PowerShell Verb-Noun naming scheme and have a BH prefix to the noun (e.g. Get-BHNode, Set-BHOperator, …)

At the center of the module is the Invoke-BHAPI cmdlet. This is the cmdlet that handles the signature and calls the API with Invoke-RestMethod and session connection details. To avoid having to repeat them at each request, server details are stored in a $BHSession variable (created with the New-BHSession cmdlet).

The Invoke-BHAPI cmdlet uses this $BHSession variable when calling the BloodHound REST API. Most of the other commands in the module are simple wrappers that use the Invoke-BHAPI command under the hood, and unpack the returned JSON into PowerShell objects.

Note: For extra safety, BloodHound Operator requires the $TokenKey to be passed as SecureString when creating a session.

Getting started with BloodHound Operator would look like this:

# Load tool
. .BloodHoundOperator.ps1

# Token ID
$TokenID = Get-Clipboard

# Token Key (SecureString)
$TokenKey = Get-Clipboard | Convertto-SecureString -AsPlainText -Force

# Create BHCE Session (localhost)
New-BHSession -TokenId $TokenID -Token $TokenKey

# AND/OR

# Create BHE Session
New-BHSession -Server instancename.bloodhoundEnterprise.io -TokenID $TokenID -Token $TokenKey

If everything went well, you should now be able to talk to the BloodHound API. You will be authenticated as long as you don’t close your PowerShell terminal, and can now use the other cmdlets in the module.

The Get-BHOperatorHelp will return a cheat sheet with a list of all the available cmdlets and their aliases.

# List BloodHoundOperator cmdlets
Get-BHOperatorHelp | ft
Cmdlet                      Alias                 Description
------ ----- -----------
Get-BHComposer Get BloodHound Composer
Invoke-BHComposer BHComposer Invoke BloodHound Composer
New-BHComposer New BloodHound Composer
Get-BHComposerLog BHLog Get BloodHound Composer Logs
Get-BHSession BHSession Get BloodHound API Session
New-BHSession New BloodHound API Session
Remove-BHSession Remove BloodHound API Session
Select-BHSession BHSelect Select BloodHound API Session
Set-BHSession Set BloodHound API Session
Get-BHAPI BHAPIInfo Get BloodHound API Info
Invoke-BHAPI BHAPI Invoke BloodHound API call
Get-BHServerAuditLog BHAudit Get BloodHound Server Audit Log
Get-BHServerConfig BHConfig Get BloodHound Server Config
Set-BHServerConfig Set-BHConfig Set BloodHound Server Config
Get-BHServerFeature BHFeature Get BloodHound Server Feature
Set-BHServerFeature Set-BHFeature Set BloodHound Server Feature
Get-BHServerSAMLEndpoint BHSAMLEndpoint Get BloodHound SAML Endpoints
Get-BHServerSAMLProvider BHSAMLProvider Get BloodHound SAML Provider
New-BHServerSAMLProvider New-BHSAMLProvider New BloodHound SAML Provider
Remove-BHServerSAMLProvider Remove-BHSAMLProvider Remove BloodHound SAML Provider
Get-BHServerVersion BHVersion Get BloodHound Server version
Disable-BHOperator Disable BloodHound Operator
Enable-BHOperator Enable BloodHound Operator
Get-BHOperator BHOperator Get BloodHound Operator
New-BHOperator New BloodHound Operator
Remove-BHOperator Remove BloodHound Operator
Set-BHOperator Set BloodHound Operator
Approve-BHOperatorEULA [BHE] Approve BloodHound EULA
Get-BHOperatorHelp BHHelp Get BloodHound Operator Help
Get-BHOperatorMFAStatus BHOperatorMFA Get BloodHound Operator MFA status
Get-BHOperatorPermission BHPermission Get BloodHound Operator Permission
Get-BHOperatorRole BHRole Get BloodHound Operator Role
Revoke-BHOperatorSecret Revoke-BHSecret Revoke BloodHound Operator Secret
Set-BHOperatorSecret Set-BHSecret Set BloodHound Operator Secret
Get-BHOperatorToken BHToken Get BloodHound Operator Token
New-BHOperatorToken New-BHToken New BloodHound Operator Token
Revoke-BHOperatorToken Revoke-BHToken Revoke BloodHound Operator Token
Get-BHData BHData Get BloodHound Data
Start-BHDataAnalysis BHDataAnalysis Start BloodHound Data Analysis
Clear-BHDatabase Clear BloodHound Database
Get-BHDataCollector BHCollector Get BloodHound Data Collector
Import-BHDataCollector Import-BHCollector Import BloodHound Data Collector
Get-BHDataPosture BHPosture [BHE] Get BloodHound Data Posture
Read-BHDataSource BHRead Read BloodHound Data Source
Get-BHDataUpload BHUpload Get BloodHound Data Upload
Invoke-BHDataUpload BHDataUpload Invoke BloodHound Data Upload
Get-BHNode BHNode Get BloodHound Node
Search-BHNode BHSearch Search BloodHound Node
Remove-BHNodeFromNodeGroup Remove BHNode From BHNodeGroup
Get-BHNodeGroup BHNodeGroup Get BloodHound Asset Group
New-BHNodeGroup New BloodHound Asset Group
Remove-BHNodeGroup Remove BloodHound Asset Group
Set-BHNodeGroup Set BloodHound Asset Group
Get-BHNodeMeta BHMeta [BHE] Get BloodHound Entity Meta
Add-BHNodeToNodeGroup Add BHNode To BHNodeGroup
Get-BHPath BHCypher Get BloodHound Path
Get-BHPathComposition BHComposition Get BloodHound Path Composition
Get-BHPathFilter BHFilter Get BloodHound Path Filter
Select-BHPathFilter BHFilterSelect Select BloodHound Path Filter
Approve-BHPathFinding Approve-BHFinding [BHE] Approve BloodHound Path Finding
Get-BHPathFinding BHFinding [BHE] Get BloodHound Path Finding
Start-BHPathFinding BHPathAnalysis [BHE] Start BloodHound Path Finding
Get-BHPathQuery BHQuery Get BloodHound Path Query
New-BHPathQuery New-BHQuery New BloodHound Saved Query
Remove-BHPathQuery Remove-BHQuery Remove BloodHound Saved Query
Get-BHClient BHClient [BHE] Get BloodHound Client
New-BHClient [BHE] New BloodHound Client
Remove-BHClient [BHE] Remove-BloodHound Client
Set-BHClient [BHE] Set BloodHound Client
Get-BHClientJob BHJob [BHE] Get BloodHound Client Job
Remove-BHClientJob Remove-BHJob [BHE] Remove BloodHound Client Job
Start-BHClientJob Start-BHJob [BHE] Start BloodHound Client Job
New-BHClientToken [BHE] New BloodHound Client Token
Get-BHEvent [BHE] Get BloodHound Client Event
New-BHEvent [BHE] New BloodHound Client Event
Remove-BHEvent [BHE] Remove BloodHound Client Event
Set-BHEvent [BHE] Set BloodHound Client Event

As you can see, there is much more than just sending Cypher to the neo4j database.

I won’t go into details for each of them, but all commands have their own help page with basic examples to get you started.
You can type Get-Command <cmdletName> -Syntaxfor a quick check, or Get-Help <cmdletName> [-example] to get more info and parameters details for the specified cmdlet.
You can also check in the repo for some basic commands and simple use cases.

From that point, I guess Bob is your uncle and you are ready for some fine Dog Whispering. With some basic scripting, you could now connect BloodHound to about anything you like and automate all the BloodHound things!

Arrooo!

Let’s finish this post with a quick example: Say you want to get an overview of SharpHound’s local collection completeness (sessions and groups) for all domains in your forest… How would you do this with BloodHound Operator?

Try this PowerShell one-liner:

# Completeness Overview
BHSearch Domain | BHData | Select domain_sid,computers,session_completeness,local_group_completeness
domain_sid                                computers session_completeness local_group_completeness
---------- --------- -------------------- ------------------------
S-1-5-21-2060347052-1267569446-3012899244 3254 1 1
S-1-5-21-2610395924-764526201-926057022 745 0.25 0.52
S-1-5-21-154216139-3765964317-975149253 122 0 0
S-1-5-21-3964086162-4236782564-686963255 723 0.99 1
S-1-5-21-2617957647-2271019196-382917398 24 0.73 0.83
S-1-5-21-3702535226-3822678775-2092719578 11 1 0.75
S-1-5-21-2313391747-169311520-2776037703 137 1 1
S-1-5-21-3490181630-3036151595-206243931 28 0.10 0.29
S-1-5-21-3852379783-2626706347-3482673801 133 0.33 1
S-1-5-21-928081258-2519523466-1777930797 75 1 1
S-1-5-21-3130029613-2716909439-2417379442 245 0.67 1
S-1-5-21-1260426776-3613520948-1897206389 429 0.39 0.18
S-1-5-21-1315550684-3600191728-175942604 1454 0.77 1

Easy as that… We are back!

This post is now reaching an end and I hope you feel like taking this dog out for a walk. Feel free to ping me on the BloodHound Community Slack if you have any questions.

Arrooo!

@SadProcessor

Note: I had the pleasure of presenting this tool at the PowerShell Conference Europe in Antwerp last June. Video recording is available here if you like.


BloodHound Operator — Dog Whispering Reloaded was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.