Deriving intelligence from sensors that register human momentum within the security ecosystem serves us well, granting insight into how adversaries may, or currently are attacking IT systems. It allows us to triage signals we feel are impactful and pose a real chance of slipping through the cracks of advanced security stacks, gaining execution. Operator tradecraft intelligence is also quite useful as it articulates what opensource exploit systems are in vogue and may be combined for greater effect. Advanced adversaries are rapidly embracing opensource software and for good reason. Opensource software provides much more anonymity when compared to custom malware development, the lead-time between offensive campaigns is reduced, innovation is greatly expanded, and the flying of false flag operations is possible. Nevertheless, this is not the scope of todays blog, utilizing trending UAC bypasses and combining them with an APT favorite (WMI) to gain persistence, is. Let’s dig in.
In the upcoming testing, we assume some type of initial access which results in the download and execution of our maliciousness. Our testing will then pick up at that point, deciding on proper evasion for the execution (actually gaining execution) and elevating privileges to persist on the endpoint after a reboot. In the blue team’s corner, we have Microsoft’s Defender for Endpoint (MDE) which is available for those customers using E/3 – E/5 licensing for Windows 10. We have configured the EDR in BlockMode and have enabled automated remediation for the machine group containing the endpoints. The overall attack architecture is as follows:
Muffin.exe(UAC bypass) -> GetMoving.cmd(Elevated) -> mofcomp.exe(persistence) -> WmiPrvSe.exe -> Fibres2.exe(NT SYSTEM) -> Covenant C2(C&C)
MeFirst(UAC bypass) -> WMIpers.cmd(Elevated) -> EventSubWMI.ps1(persistence) -> WmiPrvSe.exe -> script.ps1 -> Fibres.exe(NT SYSTEM) -> Covenant C2(C&C)
Executing Shellcode via Process Fibers
So, first thing we needed to do is figure out what we would execute after achieving a high integrity context – thank you trending UAC bypasses. One of the most common categories of behaviors our passive sensing technologies ingest are T1055 - Process Injections. Process injections are a great form of defense evasion as they (in a very broad sense), overtake a portion of a process’s memory and then inject their malicious intent into that process’s memory space. There are many different flavors of process injection, each with their own benefits and operational security considerations. Lately, our team has been utilizing trending process hollowing techniques (creating a process in a suspended state -> injecting shellcode -> resuming suspended process and executing shellcode) to achieve our goals but the MDE stack has caught on to these shenanigans. Our team turned to one of our newer intelligence capabilities (The Hunter Module) which utilizes Cyber Mongol’s advanced signatures to go out and find relevant operator tactics on the open internet. In this case, we put together signatures made up of API calls, text features, system binaries and associated privileges, to find shellcode injectors which utilize process fibers to execute shellcode within a process. Rooting through the treasure trove of returned data, we indeed found suitable candidates that would covertly inject shellcode into the memory space of a process.
Ok, now that that is sorted, let’s start at the beginning of “Attack 1”…executing the initial UAC bypass (Muffin.exe) that will pass on its own elevated token, to the rest of our attack chain. This UAC bypass utilizes the Microsoft signed binary ComputerDefaulst.exe which possesses an AutoElevate attribute, set to true. The bypass creates a process which inherits the high integrity context of its parent process, in our case Muffin.exe spawns GetMoving.cmd (which orchestrates the rest of our attack) and passes on its associated privileges. Something to note, the user account must be part of the local administrators group for this bypass to work. Luckily, this user configuration can be quite prevalent, in our experience.
GetMoving.cmd has three purposes.
We also added some basic OpSec by changing PoC code that requires pop-up Windows / User input and added code to relevant cpp console applications, “ShowWindow(GetConsoleWindow(), SW_HIDE);” hiding console windows. We left the console window open for GetMoving.cmd so that we could have a look at our .mof file being ingested. Lastly, we simulated a victim harmlessly opening up the Windows Store.
Now would be a great time to chat about the WMI persistence portion of the attack – Event Triggered Execution: Windows Management Instrumentation Event Subscription (T1546.003) . During our testing this week we tried two different UAC bypass techniques that have been trending, both producing similar results. They each produced alerts in MDE of varying degrees, but none were blocked from executing. Similarly, we employed two different ways of achieving WMI persistence through subscription, with only one of these techniques alerted on (mofcomp.exe). Without getting too deeply into the weeds here (deep dive), our intention was to register WMI persistence that would connect back to our Covenant C2 channel, every time the Windows Store application was launched. Of notable mention, WmiPrvSe.exe is the parent process for WMI subscription execution and this results in an integrity level of NT SYSTEM, for the resulting subscription’s action (fiber injection Covenant C2 Implant). Good score!
The noisier of the two tactics we employed to register WMI event subscriptions was to use mofcomp.exe. this Windows binary parses a .mof file (StickAround.mof) and creates a WMI permanent event subscription based on the file.
The much quieter way of registering a WMI event subscription (contrasted against the MDE stack) was to utilize PowerShell’s native ability to interact with WMI directly. Here, we used the attack architecture depicted above in “Attack 2” which possesses a few key differences when compared to "Attack 1."
This method was highly effective and was not blocked or flagged by the security stack. The only alert that was generated could actually have been misleading to an incident responder, alerting that the UAC bypass was fully remediated and blocked from executing (this UAC alert happened in both attack scenarios). A busy SOC analyst may have triaged this alert as “investigate later,” depending on their current priorities – afterall, they would have thought the compromise was rectified by the automation.
Both “Attack 1” and “Attack 2” resulted in an initial C&C channel in high integrity and a persistent channel with SYSTEM level integrity. None of these attacks were blocked from completing but “Attack 1” certainly generated more alerts that would get the operation burned.