Adaptive Adversary Emulation (Part 1): Execution Details
TLDR:
SCYTHE’s Adversary Emulation Lead Tim Schulz revisits his SANS Purple Team Summit talk “Adaptive Adversary Emulation with MITRE ATT&CK. This blog is part one of a three piece set and is focused on detailed execution. Tim reiterates that each snapshot in time during an adversary emulation should not be viewed as a permanent example of a threat environment. Tactics, adversaries, and capabilities are constantly adapting. Tim shares the advantages of adaptive emulation to maximize resources and time management. Examples of strategies are provided to enable organizations to adapt to threats effectively.


Back in 2019 at the inaugural SANS Purple Team Summit I gave a talk titled “Adaptive Adversary Emulation with MITRE ATT&CK®”. In the talk I go over how small changes to adversary emulation plans can provide significant results and allow a deliberate approach to generating iterative tests. While the focus of the threat landscape has changed some since then, I think the principles presented within it are still critical to successful purple teaming today.

I’m breaking this topic into a series of three blog posts: the first one (this one) will focus on small execution details, the second will discuss execution methods, and the third will discuss current adversary capabilities.

It can be easy within adversary emulation to focus on specific threats and view the snapshot in time as the whole, especially depending on when the emulation is built. We cite the cyber threat intelligence sources in our #ThreatThursdays to provide an insight into what our snapshot in time looked like since adversaries adapt, change tactics, and gain or deprecate capabilities. These changes mean that prior detections, indicators of compromise, and cyber threat intelligence (CTI) aren’t as reliable for protecting against the current adversary’s Tactics, Techniques, and Procedures (TTPs).

A significant advantage of adaptive emulation is that as adversaries build modular tooling, they will likely swap out parts that are detection-rich TTPs since doing a more extensive re-tooling will take more time, expertise, and resources. The iterative changes adversaries make to their TTPs allow for defenders to make small changes to adapt if the adversary behavior is well profiled. In some cases, thinking in iterative changes allows us as defenders to be proactive in security testing. For those following along in the Purple Maturity Model, this approach to testing is what Level 3: Creation looks like for Threat Understanding.

While we can’t always predict how adversaries will change their TTPs, by making small changes to adversary emulation tests and engagements, your organization can be proactive in how it seeks to adapt to the latest threats. Below are a few strategies we’ve seen that can help you adapt.

Vary Execution Details

We’re going to start with the smallest changes that can be made and are often some of the easiest to implement immediately! Changing execution details such as the command line arguments and flags, using shorthand for specific flags, or obfuscating commands can go a long way in stress testing detections. Let’s look at a few examples of how we can do this, and how being adaptive may change our testing.

For our examples, we’re going to focus on only changing one thing at a time.

Command Line Arguments and Flags

Command line arguments and flags provide user flexibility in how to use the tool, and allow us to gather different types of information. An example is using the builtin Windows tool net.exe through the Windows Command Line to enumerate users, user groups, and shares.

Enumerate Local Users: ‘net users’

Enumerate Domain Users: ‘net users /domain’

Enumerate Local Computer Groups: ‘net localgroup’

Enumerate Specific Local Computer Group: ‘net localgroup “Administrators”’

Enumerate Domain Groups: ‘net group /domain’

Enumerate Specific Domain Group: ‘net group “domain admins” /domain’

Enumerate Network Shares: ‘net share’

These are all examples of the same tool providing significantly different information depending on specific argument and flag variations. When building detections and tests for those detections, it's important to outline multiple procedures such as above to test the depth of how well they work.

Using Shorthand

Explicit command line arguments are not always required, especially in modern frameworks like PowerShell there are now shortcuts to provide users with fast access to powerful features. These shortcuts, or shorthand commands work not only for the baseline commandlets themselves but also flags. Let’s check out a few examples:

‘Get-ChildItem’ retrieves the current list of files within the directory it is executed from or that was specified in the command line argument. It can also be executed with the shorthand command ‘gci’.

Now, Get-ChildItem is a command that would provide adversaries with discovery information but also has a lot of potential for false positives with normal administration activity. Let’s look at a commandlet that can have a bigger impact: Invoke-WebRequest.

True to its name, Invoke-WebRequest “gets content from a web page on the internet”[1]. It is often used to download new payloads or malware by malicious actors and can be shortened to ‘iwr’. These types of shortcuts can bypass some detections, and malicious actors have been seen using them for that reason.

These same shortcuts can be applied to command line arguments and flags within PowerShell commands. The example here is the somewhat infamous PowerShell Execution Policy setting that Microsoft has officially said is not a security boundary for preventing malicious commands from being executed.

Typically when executing something from powershell using PowerShell.exe, you can use the -ExecutionPolicy flag and set it to Bypass to successfully execute your PowerShell command or script.

powershell.exe -ExecutionPolicy Bypass scythe_test.ps1

This can be short handed to only two letters ‘-ep’ resulting in:

powershell.exe -ep Bypass scythe_test.ps1

These types of changes using shorthand or shortcut commands can result in bypasses to overly specific detections, so it is crucial that you include these types of testing in both adversary emulation plans and any atomic testing you are performing.

Obfuscating Commands

Command obfuscation is our final example, and it is an extreme but very useful for testing. Our first example of obfuscation is a built-in flag that enables Base64 encoded PowerShell commands to run. 

To create the encoded command we use Base64 encoding within Windows (you can use tools outside of Windows too!)

$encodedcommand = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes('Get-ChildItem C:\'))

This newly encoded command is 

‘RwBlAHQALQBDAGgAaQBsAGQASQB0AGUAbQAgAEMAOgBcAA==’

We can now execute that command using PowerShell’s inbuilt ‘-encodedCommand’ flag 

powershell.exe -encodedCommand $encodedcommand

or we can pass the base64 string directly!

powershell.exe -encodedCommand RwBlAHQALQBDAGgAaQBsAGQASQB0AGUAbQAgAEMAOgBcAA==

By adding base64 encoding, it makes detecting our command a bit more difficult and requires defenders to do some processing on their own or by leveraging an external tool such as CyberChef.

Now let’s move into a tool/technique that is a bit more extreme: Invoke-Obfuscation by Daniel Bohannon. Invoke-Obfuscation is able to abuse some of the oddities of PowerShell being a full programming language and how it treats certain characters to create extremely odd looking commands that still execute with full functionality.

Using the Token -> String -> All through the Invoke-Obfuscation menu, I was able to turn 

‘Get-ChildItem C:\’ 

into

.("{0}{2}{1}"-f 'Get-Chi','tem','ldI') ((("{0}{1}" -f 'C:','{0}')) -f [ChaR]92)

And it still executes successfully as the exact same command. There is a Windows Command Line equivalent of the project called Invoke-DOSfuscation, for testers that want to obfuscate their command line tests too.

Deobfuscating these types of commands is much more difficult, because it is all technically valid syntax. There isn’t an easy button to get the deobfuscated command without using external tools and libraries like Revoke-Obfuscation, which may not be built into all endpoint protection systems.

You can either use these variation techniques individually or combine them to create a more complex series of tests for your environment. At the end of the day, what we are trying to accomplish with security testing is identifying gaps in detections, or gaining confidence in part of our defensive posture.

About the Author

Tim Schulz is SCYTHE’s Adversary Emulation Lead. He has been helping organizations build and train teams to understand and emulate cyber threats for the last six years while working at multiple FFRDCs. He is the author of the Purple Maturity Model, and has given talks on Adaptive Emulation with ATT&CK and Technical Leadership.

About SCYTHE

SCYTHE provides an advanced attack emulation platform for the enterprise and cybersecurity consulting market. The SCYTHE platform enables Red, Blue, and Purple teams to build and emulate real-world adversarial campaigns in a matter of minutes. Customers are in turn enabled to validate the risk posture and exposure of their business and employees and the performance of enterprise security teams and existing security solutions. Based in Arlington, VA, the company is privately held and is funded by Gula Tech Adventures, Paladin Capital, Evolution Equity, and private industry investors.