Cobalt Strike Sleep Python Bridge

This project started after seeing how the user community tweaks and tunes Cobalt Strike. I was inspired by @BinaryFaultline and @Mcgigglez16 in their project https://github.com/emcghee/PayloadAutomation and blog post http://blog.redxorblue.com/2021/06/introducing-striker-and-payload.html. They created a clever way to interact with a teamserver without the GUI.

Before I get too far, I’ll touch on Aggressor scripting and the Sleep language. Remember that Cobalt Strike is a framework and is extensible by design using the Aggressor script language. It allows users to modify or control the framework with a script that is loaded through the GUI or headless client. Aggressor provides a great deal of flexibility, but the Sleep language at the heart of Aggressor is how these extensions must be written.

What is this Sleep-Python Bridge?

This project is an experiment on extending Cobalt Strike with python instead of Aggressor or Sleep.

NOTE:
This project is very much in BETA. The goal is to provide a playground for testing and is in no way an officially supported feature. Perhaps this could be something added in the future to the core product.

How does this work?

The heart of this bridge is a python implementation of a headless Cobalt Strike client. This is achieved by using the Aggressor Script Console, provided by agscript, as the engine. Agscript allows for headless interaction with Cobalt Strike. The “bridge” works by using python helper functions in sleepy.py to generate the needed Sleep commands expected by the agscript console. Instead of writing the Sleep functions, striker.py provides helper functions that abstract Sleep and allows the use of python. In other words, this is a python wrapper to the console provided by agscript.

Notable changes from the original project

Because the PayloadAutomation project inspired this, it started with much of the same code, but I wanted to tweak to use the components needed to act as an agscript wrapper. This included:

  • Renaming from Payload_Automation to sleep_python_bridge. This project is more than payload generation.
  • Changing from a PyPI library to local modules. This was done for testing and may be a good candidate for a python library after extensive testing.
  • Updating and adding helpers to match Aggressor versions.
  • Adding ability to load external script.

What can you do with this “bridge?”

In short, anything you can do with Aggressor, you can do with this bridge via python: extract data, make operation decisions, automate beacon tasks, etc.

The best way to show what can be done is with a few examples.

Examples

Log Tracker

Beacon logs are available at runtime in a teamserver or through the Beacon log files saved on the teamserver. The data is always there, but may not be presented in a way you would like. This is an example of log tracker that uses an HTML data grid to quickly view Beacon logs.

beaconlogtracker.py is a script that connects to a teamserver, extracts the running Beacon logs every 30 seconds, saves to beaconlogs.json, and displays in a searchable and sortable HTML data grid.

Beacon logs are always saved to the logs directory, but this is an alternate way to track the in memory logs with an alternate viewer. If the teamserver is restarted the in-memory logs are lost and you must refer to the logs stored in the logs directory on the teamserver. This script keeps in-memory logs synced to the file beaconlogs.json. This way you have a quick and easy way to visualize all data without digging through the logs directory even if Cobalt Strike is restarted.

Start the script by having it connect to your teamserver to sync logs every 30 seconds:

beaconlogtracker.py

Although the GUI is not needed, you can see the client logged on and that it provides feedback as it collects logs:

Log tracker event logs

Video Demo

This demo shows the HTML data grid view. It uses the beaconlogs.json file created by the log tracker script as its data source. The data grid allows for quick sorting or filtering or Beacon logs. The output from long commands is truncated and can be expanded. This could be a nice alternate view for a Red Team operator or a Red Team lead.

Demo of the HTML log viewer

Payload Generator

A feature often requested by Red Team operators is the ability to create payloads programmatically without the need for the Cobalt Strike GUI. The project referenced at the beginning of the blog did this with a payload generator. This was great, but there is a unique challenge. Aggressor provides several hooks to influence how a payload is built. These hooks are used by the various kits (i.e., artifact kit, sleep mask kit, or UDRL kit). They are normally used by loading an Aggressor Script through the GUI. This project was extended to allow the loading of external scripts. Without this, using this payload hooks would be difficult. This code could easily be extended to pass the payloads to external functions to add custom obfuscation, embed in a customer loader, or any other modification.

The payload generator script connects to the teamserver, loads the additional scripts, and creates payloads.

payloadgenerator.py

Using the event log for output, the payload generator script displays its progress as it loads the various scripts.

Event log output

To keep this somewhat modular, the payload generator script uses a base payload_scripts.cna file as a script loader. This points to all the modules that should be loaded.

payload_scripts.cna used as an ‘init’ script to load other modules

Beacon Grapher

The script beacongrapher.py connects to a teamserver, extracts Beacon metadata, and creates a JSON file that is used to display a javascript directed graph. The connection and extraction of data is functional, but the directed graph is a simple example. It could be refined to be more useful in a production environment.

The Beacon grapher script connects to the teamserver and extracts the Beacon metadata as a python object to save to JSON.

beacongrapher.py

Here’s an HTML directed graph view of the Beacon log:

directed graph view of beacons

Video Demo

Demo of the beacon graph

What next?

Take a look at the project on GitHub. https://github.com/cobalt-strike/sleep_python_bridge

I’m providing this as an idea. Feel free to take this and expand upon it. I only ask the your share your work or ideas. Perhaps we can make this an official part of the product at some point in the future.

Thanks to the Community

I want to give a thanks to the Cobalt Strike Community for all the great work and ideas with a special thanks to @BinaryFaultline and @Mcgigglez16 on their work in the project, Payload Automation – https://github.com/emcghee/PayloadAutomation.

How to Extend Your Reach with Cobalt Strike 

We’re often asked, “what does Cobalt Strike do?” In simple terms, Cobalt Strike is a post-exploitation framework for adversary simulations and Red Teaming to help measure your security operations program and incident response capabilities. Cobalt Strike provides a post-exploitation agent, Beacon, and covert channels to emulate a quiet long-term embedded actor in a network.  

If we as security testers and red teamers continue to test in the same ways during each engagement, our audience (i.e., the defensive side) will not get much value out of the exercises. It’s important to be nimble. Cobalt Strike provides substantial flexibility for users to change their behavior and adapt just as an adversary does. For example, Malleable C2 is a Command and Control language that lets you modify memory and network indicators to control how Beacon looks and feels on a network.  

Cobalt Strike was designed to be multiplayer. One of its foundational features is its ability to support for multiple users to access multiple servers and share sessions. Enabling participation from users with different styles and skillsets further varies behavior to enrich engagements.   

While there are also numerous built-in capabilities, one of which we’ll discuss below, they are limited to what the team adds to the tool. One of our favorite features of Cobalt Strike is its user developed modules, through which many of the built-in limits are overcome. In fact, users are encouraged to extend its capabilities with complementary tools and scripts to tailor the engagements to best meet the organization’s needs. We wanted to highlight a few ways we’ve recently seen Cobalt Strike users doing just that to conduct effective assessments.   

Interoperability with Core Impact 

Contrary to many perceptions, Cobalt Strike is actually not a penetration testing tool. As we mentioned earlier, we identify as a tool for post-exploitation adversary simulations and Red Team operations. However, we have recently begun offering interoperability with Core Impact, which is a penetration testing tool with features that align well with those of Cobalt Strike.  

Core Impact is typically used for exploitation and lateral movement and validating the attack paths often associated with a penetration test. Used by both in-house teams as well as third-party services, Core Impact offers capabilities for remote, local, and client-side exploitation. Impact also uses post-exploitation agents, which, while they don’t have a cool name like “Beacon,” are versatile in both their deployment and capabilities, including chaining and pivoting.   

While a previous blog dives deeper into the particulars, to quickly summarize, the interoperability piece comes in the form of session passing between both platforms. Those with both tools can deploy Beacon from within Core Impact. Additionally, users can spawn an Impact agent from within Cobalt Strike. If you have Cobalt Strike and would like to learn more, we recommend requesting a trial of Core Impact to try it out. 

Integration with Outflank’s RedELK Tool 

RedELK is an open-source tool that has been described by its creators as a “Red Team’s SIEM.” This highly usable tool tracks and sends Red Teams alerts about the activities of a Blue Team by creating a centralized hub for all traffic logs from redirectors to be sent and enriched.  Gaining visibility into the Blue Team’s movements enables Red Teams to make judicious choices about their next steps. These insights help Red Teams create a better learning experience and ensure Blue Teams get the most out of their engagements. 

Additionally, it also centralizes and enriches all operational logs from teamservers in order to provide a searchable history of the operation, which could be particularly helpful for longer and larger engagements. This all sounds like an ideal integration for Cobalt Strike users, right? While the sub-header is a fairly large spoiler, it is nonetheless very exciting that RedELK does fully support the Cobalt Strike framework.  

Community Kit Extensions  

We can’t say enough good things about the user community. So many of you have written first-rate tools and scripts that have further escalated the power of Cobalt Strike—we feel like an artist’s muse and the art the community creates is amazing. However, many of these extensions are tricky to find, so not everyone has had the opportunity to take advantage and learn from them. In order to highlight all of this hard work, we’ve created the Community Kit. This central repository showcases projects from the user community to ensure that they’re more easily discovered by fellow  security professionals. 

We encourage you to check it out to see the fantastic work of your peers which can help take raise the level of your next security engagement and may even inspire you to create and submit your own. Check back regularly as new submissions are coming in frequently.  

A Dynamic Framework  

Cobalt Strike was intentionally built as an adaptable framework so that users could continually change their behavior in an engagement. However, this flexibility has also enabled both expected and unexpected growth of the tool itself. Planned additions like the interoperability with Core Impact allows users to benefit from session passing, while unanticipated extensions like those in the community kit are equally welcome, as they enable users to truly make the tool their own. Ultimately, we’re excited to see such dedication to this tool from all angles, as it motivates us all to keep advancing Cobalt Strike to the next level so users can keep increasing the value of every engagement.   

Want to learn more about Core Impact? 

Get information on other ways Core Impact and Cobalt Strike complement one another for comprehensive infrastructure protection. 

TeamServer.prop

Following the 4.4 release, you may have noticed a warning message when starting your teamserver:

The missing file is optional and its absence does not break the teamserver. It contains a number of optional parameters that can be used to customize the settings used to validate screenshot and keylog callback data, which allows you to tweak the fix for the “HotCobalt” vulnerability. You can suppress the warning by creating an empty file called TeamServer.prop and saving it in your Cobalt Strike directory.

An example TeamServer.prop file can be downloaded from the Cobalt-Strike/TeamServerProp GitHub repository here. We recommend that either an empty “TeamServer.prop” file is created, the file is created but the default settings are used, or the warning is simply ignored. If, however, you want to make changes to those settings, you’re now able to do so.

The default TeamServer.prop file contains the following:

#Cobalt Strike Team Server Properties
#Fri May 07 12:00:00 CDT 2021
# ------------------------------------------------
# Validation for screenshot messages from beacons
# ------------------------------------------------
# limits.screenshot_validated=true
# limits.screenshot_data_maxlen=4194304
# limits.screenshot_user_maxlen=1024
# limits.screenshot_title_maxlen=1024
# Stop writing screenshot data when Disk Usage reaches XX%
# Example: Off
#          "limits.screenshot_diskused_percent=0"
# Example: Stop writing screenshot data when Disk Usage reaches 95%
#          "limits.screenshot_diskused_percent=95"
# Default:
# limits.screenshot_diskused_percent=95
# ------------------------------------------------
# Validation for keystroke messages from beacons
# ------------------------------------------------
# limits.keystrokes_validated=true
# limits.keystrokes_data_maxlen=8192
# limits.keystrokes_user_maxlen=1024
# limits.keystrokes_title_maxlen=1024
# Stop writing keystroke data when Disk Usage reaches XX%
# Example: Off
#          "limits.keystrokes_diskused_percent=0"
# Example: Stop writing keystroke data when Disk Usage reaches 95%
#          "limits.keystrokes_diskused_percent=95"
# Default:
# limits.keystrokes_diskused_percent=95
  • Lines starting with “#” are comments.
  • limits.*_data_maxlen is the maximum size of screenshot/keylog data that will be processed. Callbacks exceeding this limit will be rejected.
  • limits.*_validated=false means that the three following “…_maxlen” settings are ignored
  • Setting any of the “…_maxlen” settings to zero will disable that particular setting
  • limits.*_diskused_percent sets the threshold for callback processing. Callbacks are rejected when disk usage exceeds the specified percentage
    • limits.*_diskused_percent=0 (zero) disables this setting
    • Valid values are 0-99

Introducing Cobalt Strike Community Kit

What is Community Kit?

Cobalt Strike is a post-exploitation framework designed to be extended and customized by the user community. Several excellent tools and scripts have been written and published, but they can be challenging to locate. Community Kit is a central repository of extensions written by the user community to extend the capabilities of Cobalt Strike. The Cobalt Strike team acts as the curator and provides this kit to showcase this fantastic work.

Initially, the kit will be a maintained list of community created projects hosted on GitHub. It will highlight projects updated in the last 30 days and uses GitHub stars as an optional popularity ranking.

The community kit is hosted on the Cobalt Strike GitHub account

https://cobalt-strike.github.io/community_kit/

 

I want to thank the security community for creating great projects. Keep up the good work!

 

A word of caution (trust but verify)

The links in this resource point to public resources. Use caution before using. Review the source code and compile binaries yourself.

Disclaimer

These links are being provided as a convenience and for informational purposes only; they do not constitute an endorsement or an approval by HelpSystems of any of the products, services or opinions of the corporation or organization or individual. HelpSystems bears no responsibility for the accuracy, legality or content of the external site or for that of subsequent links. Contact the external site owner for answers to questions regarding its content.

 

Cobalt Strike 4.4: The One with the Reconnect Button

Cobalt Strike 4.4 is now available. This release puts more control into your hands, improves Cobalt Strike’s evasive qualities and addresses a number of smaller changes requested by our users… and yes! We’ve added a reconnect button!

User Defined Reflective DLL Loader

Cobalt Strike has a lot of flexibility in its Reflective Loading foundation but it does have limitations. We’ve seen a lot of community interest in this area, so we’ve made changes to allow you to completely bypass that and define your own Reflective Loading process instead. The default Reflective Loader will still be available to use at any time.

We’ve extended the changes that were initially made to the Reflective Loader in the 4.2 release to give you an Aggressor Script hook that allows you to specify your own Reflective Loader and completely redefine how Beacon is loaded into memory. An Aggressor Script API has been provided to facilitate this process. This is a huge change and we plan to follow up with a separate blog post to go into more detail on this feature. For now, you can find more information here. The User Defined Reflective Loader kit can be downloaded from the Cobalt Strike arsenal.

Avoid localhost Sysmon Event 22 for Beacon Metadata Resolution

When Beacon starts, it resolves metadata to send back to Cobalt Strike. Previously, Beacon stuck out like a sore thumb in mature environments since the method used to resolve this metadata triggered Sysmon event 22 (DNS Query) and had become a way to reliably fingerprint Beacon every time it runs. The 4.4 release modifies how this metadata is resolved so that this no longer happens.

User-defined sleep_mask mask/unmask Stub

The sleep_mask is Cobalt Strike’s ability to mask and unmask itself in memory. The goal of this feature is to push memory detections away from content-based signatures. Although sleep_mask can encode Beacon’s data and code (if the agent is in RWX memory), the static stub is still a target for in-memory hunting based on content.

To combat this, we have made the sleep_mask stub user-definable via a kit that can be downloaded from the Cobalt Strike arsenal. Full details on this feature and how to use it can be found here and like the Reflective Loader changes, we plan to go into full detail in a separate blog post.

Reconnect button

Hands down, the single most requested change on the Cobalt Strike backlog is the addition of a reconnect button. You asked (and asked, and asked!) and we listened – but we didn’t just give you a reconnect button. If your Cobalt Strike client detects that a teamserver has been disconnected, it will attempt to reconnect automatically. The automatic reconnect attempts will repeat until either the connection has been re-established, or you choose to stop the process.

If disconnection is user-initiated from the menu, toolbar, or switchbar server button, a reconnect button appears and this allows you to manually reconnect to the teamserver.

Feature requests

We love to hear from our users – both feedback on what’s working, and requests to change things that aren’t. In addition to the reconnect button, we’ve made a few changes in this release to specifically address items raised by you.

A lot of users wanted us to add a way to persist aliases specified when renaming teamservers on the server switchbar in the main Cobalt Strike UI, so we have changed the New Connection dialog to facilitate this. When adding a new connection, you can now specify an alias for that teamserver. The alias is what you’ll see on the switchbar in the main Cobalt Strike UI. Likewise, if you rename a teamserver on the switchbar, this will update the alias for that connection. This change will be reflected in the New Connection dialog. You have the option to switch between the alias and connection view on the New Connection dialog.

Another change requested by our users was to add a way to view the Malleable C2 profile in use by your teamserver(s) in the Cobalt Strike UI. This new option can be found in the help menu (Help -> Malleable C2 Profile).

One final feature request to mention is that we’ve updated c2lint to return a result code upon completion, which can be parsed when scripting. The return codes are:

0 if c2lint completes with no errors
1 if c2lint completes with warnings
2 if c2lint completes with errors
3 if c2lint completes with both warnings and errors

The number of detected errors and warnings are also displayed if any are found.

Vulnerability fix (CVE-2021-36798)

A denial of service (DoS) vulnerability (CVE-2021-36798) was found in Cobalt Strike. The vulnerability was fixed in the scope of the 4.4 release. More information can be found here.

Other enhancements

The failover host rotation strategy that was added in the 4.3 release has been improved to parse the content of the response as well as the return code before deciding whether failover needs to be actioned. This change makes the strategy much more reliable.

One final change to mention is the addition of an allow_useragents option to the http-config block in the Malleable C2 profile, to complement the block_useragents option that was added in the 4.3 release. This new option allows you to have better control over which user agents to respond to. Note that the settings are exclusive. You cannot specify values for both allow_useragents and block_useragents in the same Malleable C2 profile.

To see a full list of what’s new in Cobalt Strike 4.4, please check out the release notes. Licensed users can run the update program to get the latest version. To purchase Cobalt Strike or ask about evaluation options, please contact us for more information.

Cobalt Strike DoS Vulnerability (CVE-2021-36798)

SentinelOne discovered a denial of service (DoS) vulnerability in Cobalt Strike. The bug (aka Hotcobalt) can cause a denial of service on a teamserver by using a fake beacon sending abnormally large screenshots.

This bug has been fixed in Cobalt Strike 4.4

Consider mitigating this risk to a teamserver by hardening your C2 infrastructure.

  • Update to Cobalt Strike 4.4
  • Disable staging on versions of Cobalt Strike prior to 4.4
  • Limit access to your teamserver infrastructure to only trusted sources

Thank you, SentinelOne working with us and responsibly disclosing this bug.

References:

  • https://labs.sentinelone.com/hotcobalt-new-cobalt-strike-dos-vulnerability-that-lets-you-halt-operations/

Introducing Mimikatz Kit

You can now update Mimikatz between Cobalt Strike releases. Updates will periodically be made available to licensed users via the Arsenal as the Mimikatz Kit.

Usage:

  • Download and extract the .tgz from the Arsenal (Note: The version uses the Mimikatz release version naming (i.e., 2.2.0.20210724)
  • Load the mimikatz.cna aggressor script
  • Use mimikatz functions as normal

Using a mimikatz command will show output in the Script Console indicating a custom version is being used.

 

 

 

CredBandit (In memory BOF MiniDump) – Tool review – Part 1

One of the things I find fascinating about being on the Cobalt Strike team is the community. It is amazing to see how people overcome unique challenges and push the tool in directions never considered. I want explore this with CredBandit (https://github.com/xforcered/CredBandit). This tool has had updates since I started exploring. I’m specifically, looking at this version for this blog post.

 

In part 2, I ‘ll explore the latest version and how it uses an “undocumented” feature to solve the challenges discussed in this post.

 

Per the author:

CredBandit is a proof of concept Beacon Object File (BOF) that uses static x64 syscalls to perform a complete in memory dump of a process and send that back through your already existing Beacon communication channel. The memory dump is done by using NTFS transactions, which allows us to write the dump to memory. Additionally, the MiniDumpWriteDump API has been replaced with an adaptation of ReactOS’s implementation of MiniDumpWriteDump.
When you dig into this tool,  you will see that CredBandit is “just another minidump tool.” This is true, but there are some interesting approaches to this.
My interest in CredBandit is less from the minidump implementation but the “duct tape engineering” used to bend Beacon to anthemtotheego‘s will.

CredBandit uses an unconventional way of transferring in memory data through Beacon by overloading the BEACON_OUTPUT aggressor function to handle data sent from BeaconPrintf() function.

There are other interesting aspects to this project, namely:

    • Beacon Object File (BOF) using direct syscalls
    • In memory storage of data (The dump does not need to be written to disk)
    • ReactOS implementation of MiniDumpWriteDump
You can read more about the minidump technique here (T1003-001) or here (Dump credentials from lsass without mimikatz).

 

Note on the Defense Perspective

Although the focus on this post is to highlight an interesting way to bend Cobalt Strike to a user’s will, it does cover a credential dumping technique. Understanding detection opportunities of techniques vs. tools is an important concept in security operations. It can be helpful to highlight both the offense capabilities and defense opportunities of a technique. I’ve invited Jonny Johnson (https://twitter.com/jsecurity101) to add context to the detection story of this technique, seen below in the Detection Opportunities section.

Quick Start

Warning: BOFs run in Beacon’s memory. If they crash, Beacon crashes. The stability of this BOF may not be 100% reliable. Beacons may die. It’s something to consider if you choose to use this or any other BOF.

CredBandit is easy to use, but don’t that fool you into thinking it isn’t a clever approach to creating a minidump. All the hard work has been done, and you only need a few commands to use it.

The basic process is as follows:

  1. Clone the project: https://github.com/xforcered/CredBandit
  2. Compile CredBandit to a BOF
  3. Load the aggressor script in Cobalt Strike
  4. Launch a beacon running in context with the necessary permissions (i.e., high integrity process running as administrator)
  5. Locate the PID of LSASS
  6. Run CredBandit
  7. Wait …. 🙂
  8. Convert the CredBandit output into a usable dump
  9. Use Mimikatz to extract information from the dump

Consult the readme for details.

Let’s See This in Action

Load the aggressor script from the Cobalt Strike manager

Get the PID of LSASS

Interact with a beacon running with the permissions needed to dump LSASS memory and get the PID of LSASS.

An output of PS gives us a PID of 656.

 

Run CredBandit to capture the minidump of LSASS

Loading the MiniDumpWriteDump.cna aggressor script added the command credBandit to Beacon.

Running help shows we only need the PID of LSASS to use the command credBandit.

This will take time. Beacon may appear to be unresponsive, but it is processing the minidump and sending back chunks of data by hijacking the BeaconPrintf function. In this example, over 80mb in data must be transferred.

Once the Dump is complete, Beacon should return to normal. A word of caution: I had a few Beacons die after the process completed. The data was successfully transferred, but the Beacon process died. This could be due to the BOF being functional but missing error handling, but I did not investigate.

NOTE: The CredBandit aggressor script, MiniDumpWriteDump.cna, changed the behavior of BEACON_OUTPUT. This can cause other functions to fail. You should unload the script and restart the Cobalt Strike client or use RevertMiniDumpWriteDump.cna to reverse the changes.

Convert the extracted data to a usable format

The file dumpFile.txt is created in the cobaltstrike directory. This file is the result generated by  “highjacking” the BEACON_OUTPUT function to write the received chunks of data from the BeaconPrintf function.

Run the cleanupMiniDump.sh command to convert this file back into something useful:

./cleanupMiniDump.sh

You will now have two new files in the cobaltstrike directory: .dmp and .txt.

The .txt is a backup of the original dumpFile.txt.

The .dmp is the minidump file of LSASS.

Use Mimikatz to extract information from the dump

At this point, we are done with CredBandit. It provided the dump of LSASS. We can now use Mimikatz offline to extract information.

You can use something like the following commands:

mimikatz
mimikatz # sekurlsa::minidump c:\payloads\credBandit\lsass.dmp
mimikatz # sekurlsa::logonPasswords



BTW, dontstealmypassword

 


Demo

Here is a quick demo of the tool.

 


Breaking down the key concepts

Beacon Object File (BOF) using direct syscalls

Direct syscalls can provide a way of avoiding API hooking from security tools by avoiding the need for calling these APIs.

CredBandit uses much of work done by Outflank on using Syscall in Beacon Object Files. I won’t spend time on this but here are great resources:

In memory storage of data

The minidump output is stored in Beacon’s memory vs. being written to disk. This is based on using a minidump implementation that uses NTFS transactions to write to memory: https://github.com/PorLaCola25/TransactedSharpMiniDump

ReactOS implementation of MiniDumpWriteDump

MiniDumpWriteDump API is replaced with an adaptation of ReactOS’s implementation of MiniDumpWriteDump: https://github.com/rookuu/BOFs/tree/main/MiniDumpWriteDump

Unconventional way of transferring in memory data through Beacon via overloaded BeaconPrintf() function

This is what I find most interesting about this project. In short, the BEACON_OUTPUT aggressor function is used to send the base64 encode dump it receives as chunks from BeaconPrintf. These chunks are written to a file that can be cleaned up and decoded.

How does this hack work? It’s clever and simple. The BOF uses the BeaconPrintf function to send chunks of the base64 encoded minidump file to the teamserver. This data is captured and written to a file on disk.

The following is an example of the output file:

received output:
TURNUJOnAAAEAAAAIAAAAAAAAAAAAAAAIggAAAAAAAAHAAAAOAAAAFAAAAAEAAAAdCMAAIwAAAAJAAAAUCQAAMI6AAAAAAAAAAAAAAAAAAA...
received output:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABolPx/AAAA4AkACJUKAP2mu1yUJQAAvQTv/gAAAQAAAAcAAQDuQgAACgABAO5CPwAAAAA...
received output:
AAAAAAAAAAAAAAAAAAAAAAAAAAC5kPx/AAAAoA4A94kOABHEhU5sJwAAvQTv/gAAAQACAAYAAQDuQgAACgABAO5CPwAAAAAAAAAEAAQAAgA...
received output:
AAAAAAAAAAAAAAAYkfx/AAAAoAcADk4IABy/Gt86KQAAvQTv/gAAAQACAAYAAQDuQgAACgABAO5CPwAAAAAAAAAEAAQAAgAAAAAAAAAAAAA...

This minidump file is rebuilt using the script cleanupMiniDump.sh. Credential material can be extracted using Mimikatz.


 Adjusting the Technique

The heart of this technique is based on accessing and dumping LSASS. Instead of using the suspicious activity of payload.exe accessing lsass.exe, you could find a process that regularly accesses LSASS, inject into that process, and perform your dump.

The BOF (https://github.com/outflanknl/FindObjects-BOF) may help you locate a process that has a handle to lsass.exe using similar OPSEC as CredBandit by using a BOF and direct systems calls. FindObjects-BOF is “A Cobalt Strike Beacon Object File (BOF) project which uses direct system calls to enumerate processes for specific modules or process handles.

Give it a try!


Detection Opportunities

Although the focus on this post was to highlight an interesting way to bend Cobalt Strike to a user’s will, it does cover a credential dumping technique. Understanding detection opportunities of techniques vs. tools is an important concept in detection engineering. I’ve invited Jonny Johnson (https://twitter.com/jsecurity101) to provide context to the detection story of this technique.

Jonny’s detection note are in the left column, and I hae added my take in the right.

Detection Story by Jonny Joe’s comments
Before we can start creating our detection we must identify what is the main action of this whole chain – opening a handle to LSASS. That will be the core of this detection. If we detect on the tool or code specifically, then we lose detection visibility once someone creates another code that uses different functions. By focusing on the technique’s core behavior, we prevent manually creating a gap in our detection strategy. For this piece I am going to leverage Sysmon Event ID: 10 – Process Accessed. This event allows me to see the source process that was requesting access to the target process, the target process, the granted access rights (explained in a moment), along with both the source process GUID and target process GUID.

Sysmon Event ID 10 fires when OpenProcess is called, and because Sysmon is a kernel driver, it has insight into OpenProcess in both user-mode and kernel-mode. This particular implementation uses a syscall for NtOpenProcess within ntdll.dll, which is the Native API version of the Win32 API OpenProcess.

How is this useful?

 

Within the NtOpenProcess documentation, there is a parameter called DesiredAccess.This correlates to the ACCESS_MASK type, which is a bitmask. This access is typically defined by the function that wants to obtain a handle to a process. OpenProcess acts as a middle man between the function call and the target process. The function in this instance is MiniDumpWriteDump. Although ReactOS’s implementation of MiniDumpWriteDump is being used, we are still dealing with Windows securable objects (e.g. processes and files). Due to this, we must follow Windows built-in rules for these objects. Also, ReactOS’s MiniDumpWriteDump is using the exact same parameters as Microsoft’s MiniDumpWriteDump API.

 

Don’t overemphasize tools. Fundamentally, this technique is based on the detection a process accessing LSASS.

ReactOS’s MiniDumpWriteDump is using the exact same parameters as Microsoft’s MiniDumpWriteDump API.” It is important to focus on the technique’s primitives. There can be multiple implementations by different tools but the technique can often be broken down in to primitives.

Within Microsoft’s documentation, we can see that if MiniDumpWriteDump wants to obtain a handle to a process, it must have PROCESS_QUERY_IMFORMATION & PROCESS_VM_READ access to that process, which we can see is requested in the CredBandit source code below:

However, this still isn’t the minimum rights that a process needs to perform this action on another process. After reading Microsoft’s Process Security and Access Rights we can see that anytime a process is granted PROCESS_QUERY_IMFORMATION, it is automatically granted PROCESS_QUERY_LIMITED_IMFORMATION. This has a hex value of 0x1410 (this will be used in the analytic later).

Next, we want to see the file created via NtCreateTransacted. Sysmon uses a minifilter driver to monitor file system’s stacks indirectly, so it has insight into files being written to disk or a phantom file. One thing we have to be careful with is that we don’t know the extension the actor might have for the dump file. Bottom line: this is attacker-controlled and if we specify this into our analytic we risk creating a blind spot, which can lead to an analytical bypass.

Lastly, a little icing on the cake would be to add a process creation event to this analytic as it would just provide context around which user was leveraged for this activity.

Data Sources/Events:

User Rights:

Process Access:

File Creation:

  • Sysmon Event ID 11

Process Creation:

A detection strategy hypothesis should account for potential blind spots. Blind spots are not bad, but should be identified. https://posts.specterops.io/detection-in-depth-a2392b3a7e94

Analytics:

The following analytics are not meant to be copy and paste, but more of the beginning of detection for your environment. If you only look for the access rights 0x1410, then you will create a blind spot if an actor uses ReadProcessMemory to dump LSASS. Ideally, multiple detections would be made for dumping LSASS so that blind spots could be covered along the way.

Sysmon EID 10 Process Access

Regarding Detection:

Multiple combinations of access rights may be requested based on the implementation. Focus on a query to cover minimal rights needed. This will reduce blind spots based on a specific implementation.

Regarding OPSEC:

Notice that payload.exe is accessing lsass.exe. This is due to this implementation as a BOF running directly under the context of Beacon.

BOF and syscalls can be great, but maintain OPSEC awareness.

Sysmon EID 10 & EID 11

Sysmon EID 10, 11, & 1

Detection Summary

When writing a detection the first thing I do is identify the capabilities that a tool and/or technique has. This helps me narrow in on a scope. A piece of code could be implementing 3-4 techniques. When this happens, I separate these techniques and look into them separately. This allows me to create a detection strategy per capability.
When the capability is identified and the components being used are highlighted, proper scoping can be applied. We can see a commonality between this implementation and many others. That commonality is MiniDumpWriteDump and the access rights needed for that function call. This is the foundation of our detection or base condition. However, this could be evaded if an actor uses ReadProcessMemory because there are a different set of minimum access rights needed. A separate detection would need to be created for this function. This is ideal as it applies an overlap of our detection to cover the blind spots that are related to a technique.
Pulling attributes like file creation and process creation are contextual attributes that can be applied back to the core detection (MiniDump). The detection shouldn’t rely on these attributes because they are not guaranteed to be present.

Cobalt Strike is not inherently malicious. It is simply a way for someone to implement an action. The intent behind that action is what determines a classification of malicious or benign. Consequently, I don’t focus on Cobalt Strike specific signatures, I look at the behavior/technique being implemented.

I like how Palantir outlines a method for documenting detection strategies using their Alerting and Detection Strategy Framework (ADS).
Jonny Johnson (https://twitter.com/jsecurity101)

Thanks to https://twitter.com/anthemtotheego  for creating this tool.

Stay tuned for part 2 where I ‘ll talk about how the latest version uses an “undocumented” feature to download the minidump file instead of hijacking the BEACON_OUTPUT function.

 

Conclusion

Wait?!?! This post highlighted the need to ‘hack’ Cobalt Strike because of a lack of features.  Why isn’t this part of the toolset?

Cobalt Strike is a framework. It is meant to be tuned to fit a user’s need. Projects like this help expose areas that can be improved. This helps the team add new features, update documentation, or provide examples.

 

References

Detection References:

 

 

 

New home for Cobalt Strike malleable c2 profiles and scripts

The Cobalt Strike references (malleable c2 profiles, scripts, Elevate Kit, etc.) have been consolidated under a new GitHub account. https://github.com/cobalt-strike

We understand that many blog posts (and even our documentation) have references to the original links. The original links will be available for the time being but may not be in the future.

Update your references to use the new repositories. All future updates will be made under the new account.

Create listeners with an aggressor script – listener_create_ext

This short post is a follow up to the post “Manage Cobalt Strike with Services” where I described a method to automate Cobalt Strike teamservers by creating services.

In this post, I will take a closer look at the aggressor function that is used to create listeners listener_create_ext to expanded on the documentation and provide an example.

The documentation shows three arguments. Let’s focus on $3, the key/value pairs. The key/values control the settings used to setup a listener.

From the Documentation

listener_create_ext

Create a new listener.

Arguments

$1 - the listener name
$2 - the payload (e.g., windows/beacon_http/reverse_http)
$3 - a map with key/value pairs that specify options for the listener

Let’s break down the options with an aggressor script that creates an HTTP listener. I formatted the script to be easier to read and added comments to provide a bit of guidance.

listener_create_ext(
    "HTTP",                             # Listener name, use something unique across all teamservers (i.e., server1-http)
    "windows/beacon_http/reverse_http", # Listener type, remember, payloads are driven by listeners
    %(host => "stage.host",             # Staging host, Only one staging host can be set
        profile => "default",           # The profile variant name, variants are set in the malleable c2 profile
        port => 80,                     # Port for c2 communications
        beacons => "b1.host,b2.host",   # Comma separated list of beacon hosts
        althost => "alt.host",          # host header value
        bindto => 8080,                 # The port HTTP Beacon payload web server will bind to.
        strategy => "failover-5x",      # Host rotation strategy aka fail strategy
        proxy => "http://user:pass@proxy.host:8080" # Proxy host settings 
    ) 
);

This aggressor script will create a listener that looks like this in the GUI.

References:

  • https://www.cobaltstrike.com/aggressor-script/functions.html#listener_create_ext
  • https://www.cobaltstrike.com/help-http-beacon
  • https://blog.cobaltstrike.com/2021/06/23/manage-cobalt-strike-with-services/