Sophos analysts recently encountered a new EDR-killing utility being deployed by a criminal group who were trying to attack an organization with ransomware called RansomHub. While the ransomware attack ultimately was unsuccessful, the postmortem analysis of the attack revealed the existence of a new tool designed to terminate endpoint protection software. We are calling this tool EDRKillShifter.
Since 2022, we’ve seen an increase in the sophistication of malware designed to disable EDR systems on an infected system, as customers increasingly adopt EDR tooling to protect endpoints. Sophos previously published research about AuKill, an EDR killer tool Sophos X-Ops discovered last year that was being sold commercially within criminal marketplaces.
During the incident in May, the threat actors – we estimate with moderate confidence that this tool is being used by multiple attackers — attempted to use EDRKillShifter to terminate Sophos protection on the targeted computer, but the tool failed. They then attempted to run the ransomware executable on the machine they controlled, but that also failed when the endpoint agent’s CryptoGuard feature was triggered.
How EDRKillShifter works
The EDRKillShifter tool is a “loader” executable – a delivery mechanism for a legitimate driver that is vulnerable to abuse (also known as a “bring your own vulnerable driver,” or BYOVD, tool). Depending on the threat actor’s requirements, it can deliver a variety of different driver payloads.
There are three steps to the execution process of this loader. The attacker must execute EDRKillShifter with a command line that includes a password string. When run with the correct password, the executable decrypts an embedded resource named BIN and executes it in memory.
The BIN code unpacks and executes the final payload. This final payload, written in the Go programming language, drops and exploits one of a variety of different vulnerable, legitimate drivers to gain privileges sufficient to unhook an EDR tool’s protection.
Peeling off the first layer
A superficial analysis reveals that all samples share the same version data. The original filename is Loader.exe and its product name is ARK-Game. (Some members of the research team speculated that the threat actor tries to masquerade the final payload as a popular computer game named ARK: Survival Evolved.)
The binary’s language property is Russian, indicating that the malware author compiled the executable on a computer with Russian localization settings.
All samples require a unique 64-character password passed to the command line. If the password is wrong (or not provided), it won’t execute.
When executed, EDRKillShifter loads an encrypted resource named BIN, embedded inside itself, into memory. It also copies that data into a new file named Config.ini and writes that file to the same filesystem location where the binary was executed.
The loader code then allocates a new memory page using VirtualAlloc, and writes the encrypted content into the newly allocated page. The malware then deletes the config.ini file and proceeds with decrypting the next set of payloads – the abusable driver and a Go binary. The loader uses a SHA256 hash of the input password as the decryption key of the second-layer payloads.
If the malware successfully decrypts the second-layer payloads, it creates a new thread and begins execution in that thread.
Loading the final EDR killer into memory
The second stage is obfuscated through the use of a self-modifying code technique. During runtime, the second layer alters its own instructions. Since the actual executed instructions are only revealed during execution, additional tooling or emulation is required for analysis.
The figure below further illustrates the technique. The first section shows the beginning of the self-modifying code layer. All instructions after the first call in the disassembly are nonsense at this point. If we revisit the same instruction block after executing the first call, we see a different set of instructions. The first call modifies the next set of instructions, which then modifies the next set of instructions, and so on.
The sole purpose of the final, decoded layer is to load the final payload dynamically into memory and execute it.
Analysis of the ultimate payload
All of the samples we analyzed executed a different EDR killer variant in memory. They are all written in Go and obfuscated (possibly through the use of an open-source tool named gobfuscate). Obfuscators are tools designed to hinder reverse engineering. There may be legitimate reasons for software engineers to obscure the software, such as to prevent competitors from stealing intellectual property. However, malware authors also use obfuscators to make it more difficult for security researchers to analyze malware.
Most reverse engineers rely on this obfuscated data when analyzing malware written in Go, but in this case, this key data is obscured in the compiled code. Some of this information includes:
- Strings are encrypted. They will be decrypted during runtime.
- The Go version information is gone. A lot of open-source reverse engineering tools rely on this Go version information to rebuild structures in the disassembly.
- Useful package information, or package paths, are encrypted or stripped from the final malware.
However, we were able to extract valuable information using the GoReSym tool from Mandiant.
Similarities between the final payloads
All of the unpacked EDR killers embed a vulnerable driver in the .data section. Their behavior is straightforward, like other EDR killers we have analyzed[1][2][3]. The only major difference between the two variants we looked at is the vulnerable driver being loaded and exploited.
Upon execution, both variants acquire the necessary privileges to load a driver and drop the exploitable sys file into the \AppData\Local\Temp folder. The malware generates a random filename for the driver every time it is run.
After the malware creates a new service for the driver, starts the service, and loads the driver, it enters an endless loop that continuously enumerates the running processes, terminating processes if their name appears in a hardcoded list of targets. This behavior is consistent for both variants.
It is also worth noting that both variants exploit legitimate (though vulnerable) drivers, using proof-of-concept exploits available on Github. We suspect that the threat actors copied portions of these proofs-of-concept, modified them, and ported the code to the Go language. This is a common trend we have also observed in other EDR killers, such as Terminator.
Same loader, different final payloads
The sample with SHA256 451f5aa55eb207e73c5ca53d249b95911d3fad6fe32eee78c58947761336cc60 abuses a vulnerable driver that has also been seen abused in attacks and calls itself RentDrv2. A proof-of-concept for exploiting this driver is available on Github.
The variant can also receive an additional command line argument “–list”, allowing adversaries to pass an additional list of process names as targets.
The variant with SHA256 d0f9eae1776a98c77a6c6d66a3fd32cee7ee6148a7276bc899c1a1376865d9b0 in contrast, abuses a known-vulnerable driver called ThreatFireMonitor, a component of a deprecated system-monitoring package. A proof of concept for this specific driver is also available on Github.
Mapping EDRKillShifter into the larger threat landscape
The final payload embedded into the loader changes from incident to incident (and, presumably, creator to creator). If we try to map EDRKillShifter to the larger threat landscape, it is also plausible that the loader and the final payloads are developed by separate threat actors.
Selling loaders or obfuscators is a lucrative business on the dark net. Sophos X-Ops suspects that the loader’s sole purpose is to deploy the final BYOVD payload, and that it might have been acquired on the dark net. The final EDR killer payloads are then simply being delivered by the loader itself, which consists of the layer 1 and 2 we described in our analysis above.
It is worthwhile to note that we are unable to confirm this hypothesis at this time.
Mitigations and advice
Sophos currently detects EDRKillShifter as Troj/KillAV-KG. Furthermore, behavioral protection rules that protect against defense evasion and privilege escalation block these system calls from going through. Businesses and individual people can also take additional steps to defend their machines against driver abuse:
- Sophos X-Ops strongly suggests that you check whether your endpoint security product implements and enables tamper protection. This feature provides a strong layer against such type of attacks. If you use Sophos products but don’t currently have Sophos tamper protection enabled, turn it on today.
- Practice strong hygiene for Windows security roles. This attack is only possible if the attacker escalates privileges they control, or if they can obtain administrator rights. Separation between user and admin privileges can help prevent attackers from easily loading drivers.
- Keep your system updated. Since last year, Microsoft has begun to push updates that de-certify signed drivers known to have been abused in the past.
Leave a Reply