Originally published by Pentera.
EDR (Endpoint Detection and Response) evasion techniques are becoming increasingly common amongst attackers as they evolve their strategies to bypass security measures without being detected. There are many different types of EDR evasion techniques, many of which are listed on the MITRE ATT&CK website. The complexity and evolution of these methods vary widely; some can be quite simple, exploiting known vulnerabilities or configuration errors, while others involve sophisticated techniques that adapt to countermeasures over time. One of the most popular methods is “reflective loading”.
Reflective loading is the process of injecting payloads directly to host process memory so that the OS will think that the code executed from memory belongs to the actual process. Many tools in Windows, for example, use this legitimately for debugging and virtualization purposes.
This research will cover three different variants of this technique, showing how they can be used for EDR evasion. In the end, we explain what this means for organizations and EDR vendors, and what security professionals can do to enhance their security posture.
Organizations should be aware of these attacks as they can bypass your organization’s primary defense mechanisms, leading to data breaches, operational disruption and significant financial and reputational damage.
Who should read this?
- CISOs – To learn how to better detect threats to the organization from reflective loading
- Researchers -To expand knowledge and learn new techniques
- Red Teamers / Pentesters – To gain new skills and attempt to detect possible compromised assets
- EDR companies – To adapt their product & include new identification techniques
The attack: 3 steps to bypass EDR with reflective loading
Tactic 1: Handling dependencies
The first tactic uses reflective loading to run Mimikatz, while evading AV and EDR products like Windows Defender. While Windows Defender supposedly blocked this method, we show a new way to handle dependencies. This is done by using DLL forwarding and ApiSet Improvements, allowing LoadDLL to preload DLL files from memory or disk. This means these files are imported by DLLs and EXE rather than LoadLibrary(). As a result, the attacker can load their own copy of DLLs, bypassing EDR hooks.
Tactic 2: Remote memory interactions
The second tactic shows how to implement a framework for interactions with reflectively loaded modules. This is done by using MemoryAPI to access data, BufferAPI to buffer local objects to remote memory, and ModuleAPIs to represent functions while executing code on the remote client.
Such a framework can be used to reflectively load DLLs into a remote host’s memory, allocate objects and then call functions inside the DLL. This allows using a local Reflective DLL technique on multiple hosts at once.
Tactic 3: API research
The third tactic helps overcome network latency issues when interacting with native DLL modules, by creating a “scripting language” for these interactions. This language, which we called DevalScript, is based on the following premises:
- DevalScript is a lightweight scripting language based on simple ideas:
- Operation == Command == Function(*args) => brackets
- Match some builtin operations with different brackets for a simple language
- Basic builtin operations: xxargs, xswitch, getvariable, … => complex logic
- The Double-Evaluation primitives enable transforming simple commands into a script, by chaining results of commands to arguments of other commands.
- The grammar of the language is defined in local/cnc/compile.py.
Impact
Reflective loading allows executing payload on remote hosts without being detected by XDR systems. This is because it provides the following advantages:
- Stealthiness – A reflectively loaded payload stays in memory in a separate, legitimate process. This makes it much harder to detect, compared to a regular payload that can be identified with forensics. The reflectively loaded payload will also not survive a reboot and can be turned off by the attacker in the system, which will remove its traces, which also makes it difficult to investigate.
- Flexible payload – A reflective payload can be used for various needs, liker beaconing. A generic payload, on the other hand, requires adding operations to run into the shell. This makes it simpler to execute a wide range of actions.
- Efficiency – The reflective payload is run from memory, making it quicker for the attacker and harder to detect for the defenders.
Mitigation
It’s recommended for security professionals to follow these steps:
- Isolate/segment valuable assets – Protect your crown jewels by separating them in the network so they are not easily accessible.
- Privileges – low privilege users – Implement the principle of least privilege to reduce the risk of privilege escalation and to make it harder for attackers to move laterally in your network.
- Train employees / phishing – Keep employees aware of the risks of phishing and skilled at how to detect phishing attacks. Be sure to train on the latest technologies. For example, how generative AI has changed phishing content.