Webinar Series: Purple Teaming - Validating Detection & Response Capabilities
ANGRYPUPPY is a tool for the Cobalt Strike framework (@armitagehacker), designed to automatically parse and execute BloodHound attack paths. ANGRYPUPPY was partly inspired by the GoFetch (https://github.com/GoFetchAD/GoFetch) and DeathStar (https://github.com/byt3bl33d3r/DeathStar) projects, which also automate BloodHound attack path execution. ANGRYPUPPY uses Cobalt Strike’s built-in lateral movement capabilities, and the credential-stealing capabilities of its agent, beacon.This allows for automated retrieval of sessions for management within Cobalt Strike and allows for the use of its SMB C2 communications channel for internal pivoting. Additionally, ANGRYPUPPY allows the operator to choose the technique they wish to use to perform lateral movement actions. Currently, an operator can choose psexec_psh, WMI, WinRM, or psexec techniques.The following displays a video of the tool in action within the RASTALABS environment, created by @_RastaMouse
BloodHound is an AD relationship mapping and visualization tool developed by Andy Robbins (@_wald0), Rohan Vazarkar (@CptJesus), and Will Schroeder (@harmj0y). BloodHound ultimately analyzes trust relationships in a Windows Active Directory Domain with the goal to support operators and provide the ability to analyze most efficient ways to target specific systems/users/groups.BloodHound has some shortcomings whereby a full view of the environment is required and therefore a large amount of AD data collection is necessary for it to operate.BloodHound and all of its information can be found at https://github.com/BloodHoundAD/BloodHound
Upon its initial release, BloodHound could take a long time to collect its data in large environments; well over 24 hours in certain cases. However, with recent upgrades, BloodHound can now finish collection in a fraction of the time. Primarily as a result of BloodHound, AD data collection is now coming into the spotlight of defenders, and a large amount of AD traffic can be a detection criteria for defenders. Therefore, when using BloodHound in offensive operations it’s vital to execute an attack as swiftly as possible, as accurately as possible.ANGRYPUPPY increases the speed and accuracy of executing the attack paths generated by BloodHound. In our test trials it was possible to execute a 5 hop attack within 3 minutes - one which may take an operator slightly longer to do manually, and reducing the possibility of operator error (which could alert defenders).As mentioned, AD data collection is moving into the spotlight of the defender space. Traditional lateral movement techniques are also widely detected and analyzed. Therefore such techniques would most likely be only viable against less mature organizations where the defense capability is lacking or an educated SOC is not present. As ANGRYPUPPY automates the attack, this leaves more time for project management, tactical planning and focus on achieving objectives with less time worrying about execution. Alternatively, in a mature environment this may be used as a means to simulate an actor with a financial gain agenda and more likely to follow a “smash and grab” approach.
ANGRYPUPPY ingests a BloodHound attack path in JSON format and is then able to determine the actions necessary to execute the attack path, stealing credentials or moving laterally as necessary. The operator simply types “angrypuppy” into any Cobalt Strike beacon console and is then able to import the attack path, select a lateral movement technique and execute the attack. This action is recorded in the Cobalt Strike event log, along with the operator name and the ANGRYPUPPY identifier. We do not recommend performing other lateral movement activity while ANGRYPUPPY is running.
ANGRYPUPPY running using psexec_psh as the lateral movement method.ANGRYPUPPY assigns a random identifier each time it is run, to allow for differentiation between attack paths executed. This identifier is used when the attack is started and completed, and will also be set as a beacon note when each new beacon checks in.In order to help with determining valid attack paths from current accessible sessions, the “cypher” command is also implemented to allow the operator to generate several queries based on the beacons currently in Cobalt Strike. The operator can then copy and paste these queries from the event log into the “raw query” section of BloodHound in order to determine paths to Domain Admins without having to manually check each user or computer. This attack path can then be exported as JSON after a valid single path is found, which can then be automatically executed by ANGRYPUPPY.
Output from the “cypher” command, showing Cypher queries generated from current beacons.
Cobalt Strike’s Aggressor Script has the “binfo” function to obtain information on a specific beacon. Using this information we can obtain a list of all current user sessions, along with machines. A computer is only used as a valid item for a BloodHound query if there is an administrator-level beacon on the device. This had to be enforced as BloodHound has no knowledge of current context and would often assume full machine compromise when only a low privileged beacon was present.A number of basic queries were developed with assistance from Andy Robbins. Currently, two types of queries are available:
With each query, an additional statement that selects only one unique attack path is also included, which basically just appends “LIMIT 1” to the end of the query for easy export into JSON, which we can then ingest with ANGRYPUPPY. This is to remove situations where the attack path may fork, which poses issues when sorting nodes.
To implement ANGRYPUPPY, there are two types of data that we needed to ingest from BloodHound: nodes and edges. A node is an item such as a user, a computer, or a group; an edge is the relationship between two nodes. There are several types of possible relationships between nodes, depending on node type.We quickly realized an issue upon beginning to write the JSON parsing logic for ANGRYPUPPY. BloodHound’s graph export feature, while giving us JSON that we can quickly ingest, returns nodes and edges in unordered arrays. This meant that we not only had to parse the data, but we had to find a way to sort the nodes. Luckily, the graph contains the information needed, in the form of edges. The parsing logic works out the possible nodes and determines a start node by finding a node that is not the “target” of any edge. With the first node, we are then able to step through and sort the nodes by using the “source” and “target” fields from each edge to arrange them in order.What we realized while making ANGRYPUPPY is that the type of edge doesn’t really matter for our purposes, as the action that we take for each node is solely determined by the node type, rather than the edge type. Additionally, we determined that while group nodes are necessary to sort the attack path into the correct order, we can effectively ignore the group nodes after we sort the attack path, as below:User1 --MemberOf → Group1 --AdminTo→ Computer1 In this case, the group node effectively only exists to show that User1 has admin rights to Computer1, and there is no action that we can take on the Group1 node. Thus, our parsing logic will drop all group nodes before the final attack path is generated.The attack execution is roughly described in the following flow chart:
Cobalt Strike posed certain issues due to the asynchronous nature of beacon communications. A limited number of callbacks were available and therefore many had to be implemented manually on a periodic polling basis of 1 second whereby a flag would be set and trigger another part of the code to execute.At the time of developing ANGRYPUPPY, the best way we found to handle detection and callbacks was by creating a loop that would be executed every second. This loop looked for changes in the state and flip switches that we have written in as global variables. Other sections of code would then detect these states and act accordingly.Let’s take lateral movement for example. It was necessary to implement a variable that prevents a second attempt at moving to the target machine if an attempt has already been made to move to the next target. Once the session comes back, this flag is reset, and only then do we attempt to perform the next action in the attack path.
ANGRYPUPPY is available at https://github.com/vysec/ANGRYPUPPY
Note: if any errors occur or the code hangs, you can terminate by typing “angrypuppykill”.For more information on usage, refer to the previously highlighted video.
Calvin Hedler (@001spartan), NetWorks GroupVincent Yiu (@vysecurity), MDSec ActiveBreach Operations
Security news, tips, webinars, and more straight to your inbox.