During our engagements, red team operators often find themselves operating within complex Active Directory environments. The question then becomes finding the needle in the haystack that allows the red team to further escalate and/or reach their objectives. Luckily, the security community has already come up with ways to assist operators in answering these questions, one of these being BloodHound. Having a BloodHound collection of the environment you are operating in, if OPSEC allows for it, often gives a red team a massive advantage.
As we propagate laterally throughout these environments and compromise key systems, we tend to compromise a number of users along the way. We therefore find ourselves running the same Cypher queries for each user (e.g. “Can this user get me Domain Admin?” or “Can this user help me get to my objective?”). You never know after all, there could have been a Domain Admin logged in to one of the workstations or servers you just compromised.
This led us to pose the question: “Can we automate this to simplify our lives and improve our situational awareness?”
To answer our question, we developed pyCobaltHound, which is an Aggressor script extension for Cobalt Strike aiming to provide a deep integration between Cobalt Strike and Bloodhound.
pyCobaltHound strives to assists red team operators by:
- Automatically querying the BloodHound database to discover escalation paths opened up by newly collected credentials.
- Automatically marking compromised users and computers as owned.
- Allowing operators to quickly and easily investigate the escalation potential of beacon sessions and users.
To accomplish this, pyCobaltHound uses a set of built-in queries. Operators are also able to add/remove their own queries to fine tune pyCobaltHound’s monitoring capabilities. This grants them the flexibility to adapt pyCobaltHound on the fly during engagements to account for engagement-specific targets (users, hosts, etc.).
The pyCobaltHound repository can be found on the official NVISO Github page.
Credential store monitoring
pyCobaltHound’s initial goal was to monitor Cobalt Strike’s credential cache (
Credentials) for new entries. It does this by reacting to the on_credentials event that Cobalt Strike fires when changes to the credential store are made. When this event is fired, pyCobaltHound will:
- Parse and validate the data recieved from Cobalt Strike
- Check if it has already investigated these entities by reviewing its cache
- Add the entities to a cache for future runs
- Check if the entities exist in the BloodHound database
- Mark the entities as owned
- Query the BloodHound database for each new entity using both built-in and custom queries.
- Parse the returned results, notify the operator of any interesting findings and write them to a basic HTML report.
Since all of this takes place asynchronously from the main Cobalt Strike client, this process should not block your UI so you can keep working while pyCobaltHound investigates away in the background. If any of the queries for which pyCobaltHound was configured returns an objects, it will notify the operator.
If asked, pyCobaltHound will also output a simple HTML report where it will group the results per query. This is recommended, since this will allow the operator to find out which specific accounts they should investigate.
After implementing the credential monitoring, we also enabled pyCobaltHound to interact with existing beacon sessions.
This functionality is especially useful when dealing with users and computers whose credentials have not been compromised (yet), but that are effectively under our control (e.g. because we have a beacon running under their session token).
This functionality can be found in the beacon context menu. Note that these commands can be executed on a single beacon or a selections of beacons.
Mark as owned
The Mark as owned functionality (
Mark as owned) can be used to mark a beacon (or collection of beacons) as owned in the
The Investigate functionality (
Investigate) can be used to investigate the users and hosts associated with a beacon (or collection of beacons).
In both these cases, both the user and computer associated with the beacon context will be marked as owned or investigated. Before it marks/investigates a computer pyCobaltHound will check if the computer account can be considered as “owned”. Do do so, it will check if the beacon session is running as local admin, SYSTEM or a high integrity session as another user. This behaviour can be changed on the fly however.
In addition to investigating beacon sessions, we also implemented the option to freely investigate entities. This can be found in the main menu (
Cobalt Strike >
This functionality is especially useful when dealing with users and computers whose credentials have not been compromised and are not under our control. We mostly use it to quickly identify if a specific account will help us reach our goals by running it through our custom pathfinding queries. A good use case is investigating each token on a compromised host to see if any of them are worth impersonating.
Standing on the shoulders of giants
pyCobaltHound would not have been possible with out the great work done by dcsync in their pyCobalt repository. The git submodule that pyCobaltHound uses is a fork of their work with only some minor fixes done by us.
About the author
Adriaan is a senior security consultant at NVISO specialized in the execution of red teaming, adversary simulation and infrastructure related assessments.