Security Ripcord

Cutaway Security Blog and Projects

BloodHound - Custom Queries

Veris Group’s AdaptiveThreat Divisions BloodHound is an exciting new tool to help Enterprises understand the current state, and possibly threat, of their Windows Active Directory environment. It is designed to augment Empire and, if I followed the DerbyCon talk / video correctly, the injestor will be built into Empire 2.0 to facilitate easy discovery / reconnaissance.

The BloodHound project is currently a work in progress but, like Empire, is well maintained and already functional. Documentation is still growing and I suspect that new users may find there is a bit of a learning curve until the documentation is updated. Personally, I would rather have the developers complete all of their current feature and functionality ideas and allow the documentation to be updated from the community for a while and then pull some of it into the projects wiki. To that end, here is a little bit I have learned about running queries on information BloodHound has collected.

Gathering Data

To start, data collection into the BloodHound Neo4j database needs to have been accomplished. Ingesting information directly into the database is one method, but in large environments it may be better to dump the information into CSV files to be imported into the database.

NOTE: Upcoming improvements should address any memory and speed issues that current users are experiencing.

Searching Nodes

Once collected, users should understand how to interact with the data within the Neo4j database. Each object collected by the ingestor (e.g. User, Computer, Group, Domain) can be simply queried by typing in BloodHound’s default textbox. The following image is an example of a query for every node with internal in the name field.

BloodHound Search for Internal

The default search textbox, marked, is in the upper left hand. Start typing and a short list of possible nodes will be populated in a dropdown menu. If you want to see all nodes, as shown in the image, just hit enter after typing the search term. More advanced searches can be performed using the Raw Query feature, marked, which is located at the bottom-center of the BloodHound window.

Learning how to navigate nodes and relationships in BloodHound, like any tool, takes a bit of practice. My recommendation is to conduct a search for a specific node, When the node is displayed click on it and the Node Info information should be populated.

NOTE: Just searching on a node does NOT automatically populate the node information. The node must be selected or the data in the Node Info may be the information from the last node selected.

The following image shows the information for the IT1@INTERNAL.LOCAL node. The IT1@INTERNAL.LOCAL node represents a AD Group. The Node Info for this group is displayed and shows Members, Memberships, Sessions, and other information. Select any of the numbers to see how the relate to this group. Selecting the Sessions number should display that the MCLUNE@INTERNAL.LOCAL account has an active session on DESKTOP27.INTERNAL.LOCAL.

BloodHound Default Search

Stored Queries

There are a few other ways to focus searches and relationships on information within the database using the main window and Node Info links. That is another exercise for the reader. The feature that most users will gravitate to is the Queries Tab. This tab contains some pre-build queries to demonstrate relationships important to understanding the AD deployment implications, user account session propagation within the environment, and paths to specific resources. Most users will run the Find all Domain Admins query right off the bat. (You cannot help it. Neither can I.) The following image breaks down the Query tab a bit to demonstrate important aspects.

BloodHound Domain Admin Query

First, once clicking on a Pre-Build Query the information will be displayed and it may not be easily readable or printable (for reports). This can be adjusted using the Change Layout feature which will change display modes which may help display the queried data in a more useful format for the user.

Custom Queries

Next, and the real focus of this post, is the fact that users can augment these Pre-Built Queries with Custom Queries. These could be developed to assist with client assessments and penetration tests or they could be build to assist with the documentation and baselining of a specific environment.

At the moment, I have created two different custom queries. The first selects all users in a specific domain and displays all of the Users and Group relationships. This may or may not be useful for exploitation but could help administrators, architects, and auditors understand the interdependencies and complexity of an AD implementation.

BloodHound Customer User Group Relationships Query

To customize this query it is necessary to edit the Bloodhound/src/components/SearchContainer/Tabs/PrebuiltQueries.json file. This file contains JSON entries that are parsed by the PrebuiltQueryNode.jsx script. BloodHound leverages the Cypher Query Language to interact with the Neo4j database. The following code is the custom query used to generate the graph displayed in the previous image.

        "name" : "Cutaway Test: Users / Group in Domain",
        "requireNodeSelect": true,
        "nodeSelectQuery": {
            "query": "MATCH (n:Domain) RETURN n",
            "onFinish": "MATCH (n:User) WHERE =~ ('(?i).*@' + '{}') WITH n MATCH (n)-[r:MemberOf*1..]->(m:Group) WHERE ENDS WITH ('@' + '{}') RETURN n,r,m",
            "start": "{}",
            "end": "",
            "allowCollapse": false,
            "boxTitle": "Select source domain..."

Testing Queries

The Cypher language does take a little practice. The language is operating on nodes and their relationships, thus making it a bit different to query and display specific information. The examples provided by Andrew Robbins and Rohan Vazarkar provide excellent examples of where to start with normal queries and queries that require users to select specific objects. Once a custom query is created or modified the BloodHound application needs to be rebuilt from source. While this is easy, there are easier ways to test queries without continually building and restarting.

As noted earlier, BloodHound provides a user with a Raw Query capability at the bottom-center of the application. To test queries a user just needs to copy the query from custom query code block. For queries that require users to select an object the query in the onFinish field should be used.

Cypher regular expressions are similar but slightly different from other regular expression syntaxes. The .* is a greedy representation for any content. The {} operator will contain data from the operation that immediately precedes the query. Node information are processed using variables defined by the user. For example, (n:User) will be used to process all User nodes which will be placed in the n variable. Relationships between nodes are represented by -> with a specification associated with a specific type of relationship. For example (n:User),(m:Computer), (n)<-[r:HasSession]-(m) will select nodes where a user has an active session to a computer.

My intent is not to fully explain Cypher regular expressions and node / relationship management; this should be left to the Cypher documentation. Rather, these examples need to be understood so that the user can make the appropriate updates when pasting the query into the Raw Query. For example, if a user is required to select a specific domain before processing a query the {} will need to be changed to the specific, case sensitive, domain name. If it is not, the Raw Query will not understand {} and it will either error out or it will just run continuously forcing the user to either refresh or restart BloodHound.

When testing queries using the Raw Query option I have found that refreshing and restarting BloodHound is a common issue. After all, test queries are going to initially fail until the correct syntax is determined. Fortunately, there is an easier way to test queries. This is done by connecting directly to the Neo4j database. Users can just point their browsers to http://localhost:4747, log in, and start running queries in the search box at the top of the page. Queries run or error out much quicker via this interface than in BloodHound’s Raw Query. I also like to point out this interface because it represents an excellent way to retrieve data from the Neo4j database. If the PowerShell ingestor wrote directly to the database rather than a Comma Separated Value (CSV) file, the data cannot be easily extracted via the BloodHound tool. Logging into the Neo4j database and running a query will allow a user to display information in graphical or text-based format. It also provides an export function. Thus, all user nodes could be extracted in CSV format and easily imported into other tools, if necessary.


Using and writing custom queries takes practice and troubleshooting. As with any new tool, this requires patience during the trial-and-error process. Hopefully this post will help jumpstart additional query development. It would be great to see the community force Andy and Rohan into creating query categories (i.e. Exploitation, Recon, Architecture) to logically organize the information gathered by BloodHound. After all, BloodHound is not an exploitation tool solely devoted to facilitating the exploitation of an AD environment. Rather, it is a tool designed to provide an automated visual representation of an AD environment to demonstrate how it is actually implemented, which will always be different and more accurate than manually-built representations.

Go forth and do good things,
Don C. Weber

UPDATES: Added credit to Rohan Vazarkar for default query development.