Introduction
When I talk about EDRs in this article, I mean a combination of endpoint protection (EPP) and endpoint detection and response (EDR). I also want to define the term “evasion” in the context of EDRs and malware. When I talk about the fact that it is or has been possible to bypass the EDR, the term “bypass” refers to the fact that no prevention and no detection has taken place on the part of the EDR. However, the EDR continues to collect telemetry data at the endpoint that can be used for active threat hunting.
In the meantime, from the point of view of the attackers (Red Team), there is a whole range of different techniques, such as direct system calls, indirect system calls, API unhooking, etc., which can help us as Red Teamers to evade detection by Endpoint Protection (EPP) and Endpoint Detection and Response (EDR) systems. However, even if you add various evasion features to your malware, e.g. shellcode dropper, the command and control framework (C2) used or the respective shellcode often seems to be a certain limitation. With modern Red Team C2s such as Nighthawk, Cobal Strike, Brute Ratel, etc., this seems to be less of a problem, as the stager’s shellcode or payload is already equipped with very useful evasion features such as indirect syscalls, hardware breakpoints, etc. by default.
The situation is somewhat different with freely available frameworks such as the Metasploit Framework (MSF), which can sometimes make it very difficult to bypass modern EDRs in the context of command and control connections. Whether and at what stage Meterpreter shellcode, or the execution of Meterpreter shellcode, is detected by EDRs depends on various factors such as signatures in the shellcode. Similarly, how the executed shellcode behaves in memory can be important for detection by EDRs. For example, Metasploit or Meterpreter shellcode in memory is detected by EDRs based on certain patterns.
For example, if you look at legitimate areas of memory with Process Hacker, you will see that they are of the type “Image” and also point to the associated image. If you look at a meterpreter payload in memory, you will notice that there are also some memory regions of type “private” that do not refer to an image. For example, the 4kB meterpreter stager can be identified. These types of memory regions are called “unbacked executable sections” and are usually classified as malicious by EDRs.
Similarly, from an EDR’s point of view, it is rather unusual for a thread to have, for example, memory areas in the .text (code) section marked as read (R), write (W) and executable (X) at the same time. By default, the .text section is a read-only section in the PE structure. When using a Meterpreter payload, this does not apply in its entirety, because by using the Windows API VirtualAlloc, certain areas are additionally marked as write (W) and executable (X), or the affected memory area is marked as RWX in its entirety (PAGE_EXECUTE_READWRITE).