Main Content

Heya - HollyGraceful here, I make all of this content in my spare time, like it? Please support me :)
You can donate via Bitcoin or Patreon!

Adventures in Anti-Virus Evasion

Preamble

Anti-virus is often the last line of defense to users, the ability to bypass that system is a critical one for Penetration Testers but I’m still not comfortable in giving out a complete walk through as that kind of knowledge offers great advantage to attackers but little benefit to defenders. For me, that’s the ultimate test for ethics: are we assisting defense more than attack, if we are not then the tactic or system is dangerous. Tools like Veil-Evasion often makes evasion trivial the tool is well documented. I will present in this article my findings and research in anti-virus evasion, but will not offer a complete walk through of how to get a zero score on sites like virustotal.com. Consider this an adventure, not a guide.

Veil-Evasion

For those of you who only came for a tool and guide for evasion, that exists already Veil-Evasion is part of the Veil-Framework, Evasion is a free and open-source tool which integrates nicely with Kali-Linux and Meterpreter to create payloads which automatically bypass anti-virus and they even have guides on how to use it.

Introduction

A few years ago I came up against some pretty rugged anti-virus whilst conducting a Penetration Test for a client. I did the research, put in the effort and managed to bypass the defensive technology to allow the Penetration Test to be successful. I found the challenge an interesting one and now consider it my biggest hobby – writing malicious code, bypassing anti-virus and attacking scanner engines. So here I offer a little analysis about the different techniques that I’ve tried, seen documented and ultimately I’ll run this guide right up to the point where my current research begins which I plan to present at BSides London if I get enough votes, if you’d like to see that then you can vote here: https://www.securitybsides.org.uk/talksubmissions.html. The talk includes details about attacking scanners themselves as well as evasion techniques.

Signatures and Bad Behaviour

It fairly well known that there are two main ways of detecting malicious files in the anti-virus world, the first is with signatures where when a file is known to be malicious a unique pattern is identified within a file and this can be used to identify that file as malicious when it is seen in the future. Alternatively a file can be executed, either in a virtualized or emulated environment, and the file can be monitored to determine if the actions it performs are malicious. If they are deemed as malicious then the file can be flagged and quarantined or removed. The issue here is, how do you define malicious?

Also, it’s interesting to note that I, and many others online, test my malicious payloads using the free scanning tool VirusTotal.com, however according to their own FAQ (https://virustotal.com/en/faq/#antivirus-file-scans) it would appear that many of the scanners provided by this tool do not deploy their behavioral analysis engine. However VirusTotal has its own which I’ll use where appropriate, plus there are other tools available such as Anubis, a free online behavioural scanner. (Anubis has recently been discontinued, as per their announcement: https://anubis.iseclab.org/)

Why Evade? Taking a baseline…

As Penetration Testers we have a collection of tools. These tools can be used for good and bad purposes and therefore it’s right that anti-virus packages should protect users from the potential impact of these files. In order to perform a complete penetration test we may need to bypass these protection mechanisms. Take the tool Meterpreter for example, here’s the output from VirusTotal showing that the majority of protection suites would block this tool:

A screenshot of a VirusTotal scan showing a default Meterpreter payload scoring 34 out of 51.

Encoding

If you’re using the Metasploit framework to generate payloads, there is a tool called MSFencode (MSFencode was replaced by MSFvenom as of June 8th 2015, this new tool combines MSFpayload and MSFencode into a single tool), which many many people have recommended to me for anti-virus evasion. In fact, the number of times I heard “All you need to do is encode!” has been painful.

Let me show you why: After running MSFencode on the basic meterpreter payload, here were the VirusTotal results:

File name: met-encoded.exe
Detection ratio: 35/51

35/51, it went up! So I went back to my colleagues and explained my problem and I received the most illogical response ever:  “All you need to do is encode more!”. Let’s try it:

File name: met-multiencoded.exe
Detection ratio: 33/51

You see, the problem here isn’t anything cool or special, like the AV engines using crazy behavioral analysis to determine that this is still Meterpreter, it’s simply that the signature is being applied to the decoder stub itself (in this case I used the well known encoder Shikata_ga_nai), so regardless of what is encoded with this tool, the AV engines all pick it up as malicious. Encoding multiple times doesn’t change the fact that the first decoder stub is visible in the EXE and flagged.

Hopefully this will finally finish off the idea of simply encoding to bypass anti-virus evasion:

If you come into the Metasploit channel and ask about evading anti-virus with MSFEncode, I am going to hurt you.

~~ Thelightcosine, a metasploit core developer

Templates

Another tactic, along the same logic as above, is to change the EXE template. Tools like MSFencode and now MSFvenom inject shellcode into an EXE template. The logic is, if the antivirus vendors are detecting the encoder stub then potentially they will also be detecting the default EXE templates,therefore if we swap these out potentially we’ll reduce the detection rate. Last year I had success with this simple technique, however this time around I swapped out the template for a clean EXE with zero detections and got the following results:

A screenshot of a VirusTotal scan showing a Meterpreter payload with a custom template scoring 26 out of 55.

Not such a great result.

Calling Shellcode in C

An alternative to using templates as above would be to take the shellcode produced by MSFvenom and placing it in a bare-bones executable using a C file such as this:

char buf[] = ""; // Place shellcode between " "
int main()
{
    int (*func)() = (int(*)())buf;
    func();
}

You can compile this in to a Windows EXE with a command such as this:

i686-w64-mingw32-g++ main.cpp

The logic here is the same as with templates, if the template is being detected then simply removing this from the equation should result in a lower detection rate. The results weren’t bad, but still a large number of detections:

A bare-bones C application with Shellcode injected inside scoring 15 out of 56 on a VirusTotal scan.

Packing

One method of obfuscating signatures in the code of an executable is to simply compress that executable with a packer, this way the functionality is unaffected however general signature analysis would fail. I tried this a few times, with a few different packer types that were publicly available. I got the best mileage out of kkrunchy, but that’s only 32bit – the simplest to use was upx which did surprisingly well for such a well known tool. First of all I uploaded Mimikatz32 and got a poor score of 24/56. I then uploaded Mimikatz64 to VirusTotal and got a score of 32/56 before packing and here’s the result after packing:

A Mimikatz payload packed using UPX scoring only 8 out of 56 on a VirusTotal scan.

Not bad at all for such a simple evasion step.

Taking a quick detour here, as I was playing around with lots of different techniques – at this point I actually tried out stomping on the metadata of the executable, that’s the version details, copyright notice, internal filename and other details. I replaced all of this information with NULL bytes using a hex editor and got the following:

A Mimikatz payload packed with UPX but with the metadata removed scoring 6 out of 55 on VirusTotal.

Pretty curious to see two scanners drop detections on such a simple change!

Auto-erotic Exploitation

Continuing on from the idea of injecting shellcode, there’s another method of getting it in to the system which is particularly difficult for Anti-virus scanners to detect. If you set up a stager which simply read data from the network and wrote it to a buffer that was vulnerable to a buffer overflow it would be possible to get shellcode to execute on the system in a way that is difficult for anti-virus scanners to deal detect.

Crypting

The most success I’ve had with evasion has been through the use of “crypters”, the idea here being similar to packers but instead of simply compressing the data the data is encrypted within the EXE. There are two ways to do this, the first is where the key is stored within the EXE and simply retrieved and used by staging code at the beginning of the execution process. The second method is for the EXE not to know its own key and to require the executable to bruteforce the password for the encrypted section.

This is more effective for a combination of reasons, the first being that it also makes manual analysis harder, but also many scanning engines only scan for a short period of time. By delaying execution in this way, a way that the scanner cannot bypass, it means that signatures are hidden by the cryptography and behavior is guaranteed to be delayed until at least the scanner has stopped looking.

I’m not the first person to implement this idea, in fact it was documented in Hyperion at least as far back as 2012. I’ve found that implementations like this are still detected by a small number of anti-virus companies as the encrypted sector has a high entropy. A naive way of getting around this issue is to set every second byte to be a null byte then simply get the staging stub to ignore them. This method has been effective for me in getting a reliable zero score on VirusTotal, although it does greatly increase the executable size a more space effective method of reducing the entropy could be found.

Developing an implementing a Crypter of this nature used to be a huge task, but with tools such as kkrunchy and even the leaked HackingTeam core-packer being publicly available code sources the barrier to entry is much, much lower.

A Mimikatz payload encrypted with a custom crypter scoring zero out of 55 on VirusTotal.