Macros and More with SharpShooter v2.0

In March 2018 we released SharpShooter, a framework for red team payload generation. We followed up with further updates and new techniques in June. Like many offensive tools, the framework was adopted by various threat actors and was tracked in a number of campaigns by Microsoft:

Publishing any offensive research can be an ethical dilemma, however we firmly believe that offensive research can provide a rare opportunity to drive positive change en masse. In this case that was exactly what happened as various EDRs improved the way they detected fileless malware as described in this excellent blog post by the Windows Defender ATP team who showed their approach to detecting SharpShooter.

Since our last release we’ve made further advances in the tool, incorporating new payloads and bypasses, some of which we’ll discuss in this post.

AMSI Bypass

Shortly after SharpShooter attracted the attention of the Defender ATP team, we started to receive complaints that it was being detected. Because when you release a tool you’re clearly on the hook for bypass support for life and against all defensive solutions, in August we added a module to bypass AMSI based on Tal Liberman’s AMSI research.

This technique is relatively simple, if the registry key HKCU\Software\Microsoft\Windows Script\Settings\AmsiEnable exists and is set to 0, then AMSI support is disabled. As this key exists in the Current User hive, a compromised user can add it to disable AMSI checks. The module therefore generated a small stub that is executed prior to the primary SharpShooter payload, this stub will set the AmsiEnable key to 0 and reopen the script. The release pushed with this blog post uses a slightly more elegant technique for doing this courtesy of @buffaloverflow.

Modification of this registry key is probably a good indicator that something suspicious is happening, and you would probably assume that Anti-Virus or EDR would flag this as elegantly put by @tiraniddo below:

However, as of writing this post the technique still seems to have legs, at least against Defender….

AMSI bypass with SharpShooter

Stylesheet Execution via Macros

In our previous SharpShooter blog post, I documented a new technique for stylesheet execution through COM using the XMLDOM and related COM objects. At the time this technique was relatively powerful as AMSI did not appear to be applied to scriptlet execution when processed through COM. Following up from the blog post, in September I tweeted how this could be used from a macro enabled Office document:

SharpShooter will now generate a small stub that can be used inside an Office document:

On enabling the macro, it will retrieve and transform a remotely hosted stylesheet, providing code execution in the process context of Office:

Macro generation with SharpShooter

Since recent updates to Defender, AMSI will apply to execution through scriptlets such as stylesheets; you can however use the aforementioned –amsi flag to disable it using the AmsiEnable technique in the macro which might look something like this:

We’d also recommend reading the write up by @bohops on this technique where he uses it to bypass WDAC.

Excel4.0 Macros

In October 2018, Stan Hegt described a legacy feature of Excel that allows execution of macros without VBA. Stan showed how Excel 4.0 macros could be abused to execute arbitrary code in a similar manner to VBA macros and we’ve had real success leveraging this to slip past various Anti-Virus and EDR engines as we’ll show in an upcoming EDR case study blog post.

The latest release of SharpShooter now includes the ability to generate an SLK file that will execute arbitrary shellcode using an Excel 4.0 macro; much of the code is borrowed from Stan’s proof of concept so kudos to Stan for helping make this possible.

To generate the SLK, the shellcode must first be free of null bytes which can be achieved using msfvenom to encode it, for example:

msfvenom -p generic/custom PAYLOADFILE=./payload.bin -a x86 --platform windows -e x86/shikata_ga_nai -f raw -o shellcode-encoded.bin -b '\x00’

As is widely known, SLK files do not trigger protected view so are a great target for exploiting Office. To generate the SLK payload with SharpShooter I’ve added the SLK file type as a payload type so you now just need to simply point it at the shellcode: --payload slk --output foo --rawscfile ~./x86payload.bin --smuggle --template mcafee

Here’s an example of generating an SLK that loads a Cobalt Strike beacon:

Excel4.0 macro generation with SharpShooter

Musings on Tradecraft

When we release research, it’s often proof of concept and in many cases not fully weaponised; we hope that it will plant a seed that can be taken and adapted for operational use in your own engagements. Part of this is adapting the tooling to better improve tradecraft to avoid detection or make it more tailored to your specific environment (check out @leoloobeek‘s talk on payload keying from DerbyCon).

After we released SharpShooter, various defenders talked about techniques for detecting it. Perhaps the most comprehensive write-up we saw was the two part post by Countercept, we recommend having a read of these posts for the background:

There’s a number of key indicators that are discussed in the blog posts, let’s discuss a few of them and see how we can improve tradecraft to reduce the number of indicators.

Memory Indicators

The stageless template provided with SharpShooter performs the shellcode execution by first allocating memory in the container process with VirtualAlloc, copying the shellcode to it then executing it. One of the key tells in the template is that the memory allocation is performed with EXECUTE_READWRITE permissions; a common page permission sought by threat hunters.

Improving tradecraft around this is relatively straightforward, rather than lazily allocating EXECUTE_READWRITE permissions, we can just alter the page permissions such that they’re only the permissions we require at the time and never EXECUTE_READWRITE.

To achieve this, we firstly allocate memory PAGE_READWRITE, write the shellcode to the page then use VirtualProtect to reset the page permissions to PAGE_EXECUTE_READ before executing the shellcode, a simple example is shown below:

Process Indicators

When SharpShooter executes shellcode, the supplied template uses the existing container process to do so. This of course is probably undesirable, as pointed out in the Countercept analysis as having mshta.exe or equivalent talking to the Internet is a strong indicator that something untoward could be happening.

We can improve our tradecraft to avoid this by spawning a less suspicious process to inject our implant in to, a good candidate to blend in might be iexplore.exe for example.

To do this, we can modify our template to spawn a suspended process, inject the shellcode and then resume it; expanding the previous example to spawn iexplore.exe and inject in to it using CreateRemoteThread may look as follows:

You may want to explore other more opsec injection techniques, but that’s beyond the scope for this post.

Who’s Your Daddy?

Another key indicator for detecting the default SharpShooter template discussed in the Countercept analysis is the parent process. For example when opening a JavaScript file, a running wscript.exe process with a parent of chrome.exe is probably suspicious. Although we can’t necessarily effect the parent process from the initial payload, if we’re spawning a new process and injecting in to it we can let wscript.exe exit and manipulate our parent process in the newly created container process. Parent PID spoofing is nothing new, indeed Didier Stevens discussed it back in 2009 so we won’t go into too much detail here.

To summarise the technique, the lpStartupInfo parameter of the CreateProcessA API call allows the staging application to specify a user supplied STARTUPINFOEX structure with a PROC_THREAD_ATTRIBUTE_PARENT_PROCESS attribute pointing to any arbitrary process. In some cases this can skew EDR solutions that rely on the parent child relationship to make decisions. Searching for the PID of explorer.exe and spoofing our newly created container process can make it look like the process was started from explorer rather than the browser for example. @leoloobeek has an example C# implementation for this technique. If we take a look at how it works, we see that first a handle to the desired parent process is created, then the parent process is set using UpdateProcThreadAttribute with the handle as the PROC_THREAD_ATTRIBUTE_PARENT_PROCESS attribute:

When the CreateProcess API is called we now use the EXTENDED_STARTUPINFO_PRESENT attribute to specify that the STARTUPINFOEX structure is present:

Repurposing this code in to a SharpShooter template, we must first find the PID for the parent process we want to spoof, for example explorer.exe; this is done using the CreateToolhelp32Snapshot API, for example:

Putting all this together, we are now able to inject in to a newly created container process with a spoofed parent PID without using an RWX page:

Process injection and PPID spoofing with SharpShooter

We don’t have any immediate plans to release the template but with the above code this should not be too taxing to reproduce 🙂

SharpShooter v2.0 is available on the MDSec ActiveBreach github.

This blog post was written by @domchell.

written by

MDSec Research

Ready to engage
with MDSec?

Copyright 2021 MDSec