About six months ago, with the slow death rattles of the exquisite Empire C2 drawing near, not going to lie I'm still in mourning – that and python2, I was on the hunt for a new platform to sink my teeth into. While playing around with various frameworks on offer such as SilentTrinity, Faction, Merlin (all of which have their positives), I started looking at Cobbr's Covenant framework https://github.com/cobbr/Covenant. There are too many positive elements of this framework to list, and the more I use it, the more I find. However, as a rough outline:
- It's written in one code base, C#, meaning I can use my limited knowledge of the language to add new features for the rest of the team to use (https://github.com/cybernomad1/CovenantTasks)
- As it utilises offensive .Net capabilities, the majority of tools/scripts written for PowerShell can and are being ported across.
- It's probably the simplest UI for a C2 framework I've come across.
- The task history is great for when you're writing reports/doing a 'wash-up' meeting with internal teams to track what was run when.
As fantastic as this framework is, it wasn't long before all available payloads started to flag AV products, and the omission of a shellcode launcher drastically reduced the obfuscation methods available. You're unlikely to be surprised by how many organisations' AV still lets the standard PowerShell string execute. However, some form of benign shellcode execution stager is needed to utilise the framework for more security-aware/red team engagements. As if on cue, @_rastamouse published an article on just this (https://rastamouse.me/2019/08/covenant-donut-tikitorch/).
Using the basic research in @_rastamouse's blog, I was able to incorporate the Grunt shellcode into a current set of tooling I was writing around UAC bypass, and the first version of the teams Injector was born (https://github.com/cybernomad1/Injector).
*I am now making this repo public as multiple AVs are now catching the toolset (excluding Microsoft Defender) and I've had to strip back functionality/rewrite the codebase.
The basic workflow of the tool is as follows:
- Create your malicious covenant GruntStager.exe as usual
- Use ShellcodeCreate.py (built on donut) to create base64 encoded shellcode file. This has the added bonus of the shellcode bypassing AMSI protections
- Host/transfer payload and Injector to target
- On execution, Injector will identify the current user and inject the Covenant stager shellcode under the applicable explorer process but masquerade as iExplorer.
- If the user is a local admin (that never happens, right?) Injector will attempt to bypass UAC controls.
- With this administrator access, the Injector will re-run its workflow, attempting to inject the same Covent shellcode under a system process, giving the attacker full control of the host.
Granted, having Internet Explorer running under svhost.exe as 'System' is likely to raise some eyebrows in the SOC – but the functionality is there when needed.
There are reasons why I chose to have Injector masquerade as Internet Explorer.
- It is still present at a default path on almost all Windows instances
- A worryingly high number of organisations still have Intranet-based
- websites that require it, so it's not as suspicious as one would think
Covenant attempts to masquerade its C2 traffic as legitimate web requests.
Now let's face it, using the default profile is unlikely to fool anyone for long, but you can easily create your own profiles within the Covenant GUI. Coupled with all traffic appearing to come from a valid Internet Explorer process, and you may just fool an analyst long enough to complete your objective.
Under the Hood
**Caveat 2: While I know a bit about a few languages I'm not a developer or an 'L33t' hacker – most of my tools are cobbled together from random twitter threads and Gists I find from individuals far better than me. Additionally, everything I write is from an 'it works for me' perspective.
Shellcode Injection - GruntInjection.cs:
Predominantly taken/adapted from @_ratamouse’s blog referenced earlier and his work on Tikitorch.
The basic overview of how this function works: allocate a section of memory the same size as that of your payload, but under the process information for Internet Explorer. Once this section in memory has been assigned, we then write our shellcode into this section of memory. Finally, we create a new thread for our process to run under the guise of IE.
UAC Bypass – sdclt.cs
The current UAC bypass technique included with Injector utilises the sdclt.exe executable to execute a value in the registry as a privileged user.
As with most UAC bypass techniques, the flaw comes from the fact that sdclt.exe can run with 'autoElevate' privileges, meaning it can run as a high integrity process without issuing the normal UAC windows.
To exploit the UAC Bypass method in question, Injector writes its own path to the following registry key:
By setting a 'privesc' flag at the end of the command, it also tells the binary on its second execution that it is in 'UAC Bypass mode'. It, therefore, should follow the necessary workflow to obtain a system-level shell. Upon execution of the sdclt.exe command, the registry key is then removed to limit any side effects caused by its creation.
Credit for all their work:
@_RastaMouse -> Their work on TikiTorch and shell injection formed the groundwork for how the injector operates
@Cobbr_IO -> For the SharpSploit and Covenant projects
@TheRealWover -> For the Donut library and project