David Maloney now breaks the structure of an arbitrary Metasploit payload down into essential constituents and dwells on some common obfuscation problems.So, real quick we are just going to define some terms (see right-hand image), hopefully everyone is familiar with this. In the antivirus world we are going to be talking about signatures, which is basically just pattern recognition on recognizable pieces of code. Heuristics is an AV detection mode where it is basically going to emulate the execution of the program in some manner and try and come up with a match for the behavior of the program. And then there is sandboxing, and sandboxing is where basically it just creates an isolated environment where the program can execute but doesn’t really have full permission to do all the things that it might. So, some Metasploit terms (see left-hand image). A payload is the code that an exploit actually delivers and is executed by the exploit. When we are talking about a payload it is often broken down into a stager and a stage. So a stager is the initial shellcode that we send, that is small enough to fit in whatever buffer, like a buffer overflow or any kind of memory corruption exploit, and it connects back to Metasploit and pulls down the rest of the payload, which is significantly larger, and that is what we refer to as the stage.
So this distinction between stager and stage is very important when we are talking about AV evasion, because what initially gets sent down is the stager, and that is one of the key areas where we are getting flagged.Here is a nice little analogy for how you can think about a Metasploit payload (see right-hand image). You have got your delivery system, and in this case I am throwing ms08_067 up as an example because it is everybody’s favorite exploit. Then the exploit is going to put the stager, in our case reverse_tcp, into memory. The reverse_tcp stager creates a reverse connection back to our Metasploit handler and pulls down metsrv.dll, which is the stage for Meterpreter. Metsrv.dll then has a bunch of other extensions that it comes and pulls down and loads into memory on that box. The stager creates executable memory and then connects back, pulls the stage down, puts it in that memory and executes it. Now, in an EXE this works slightly differently (see right-hand image). The exploit method is just creating that RWX memory segment from the executable and then pulling our payload down and shoving it in. One of the big problems we have currently is that whenever we drop in the EXE that executable is just storing our shellcode in a variable somewhere. We send that executable and the payload is right there recognizable inside a variable somewhere stored in memory. So the goal of my research and this talk was to discover specifically what detections are triggering on. Everyone has been talking about different techniques. Talk about packers, encrypters or some clever little things they are doing. What I wanted to know is why some things work and why others don’t. So I took all the ways that people have talked about doing antivirus evasion, broke them down piece by piece, and said: “OK, how many detections do we get when we do this thing? How many do we get when this, so that we have a real understanding of what’s going on when we get detected.” The process that I went through (see right-hand image) is that I used what’s called Metasm. Is everyone here familiar with Metasm, anyone? Metasm is a wonderful Ruby library that is an assembler, a disassembler, a C compiler, a debugger – all in one. It’s an amazing piece of software and we can use it for wonderful metaprogramming and rubying, we use this in Metasploit. What I did is I took each technique and generated C code with Metasm, compiled it into an EXE and then automatically uploaded it to VirusTotal and pulled those results down and sorted them based on what the detection was. Nobody is screaming yet, that’s surprising. I said VirusTotal. There are some problems with VirusTotal (see right-hand image). The vendors don’t deploy all of their engines to VirusTotal, so your results on that site actually are not 100% accurate. Some of them don’t put heuristics up at all, you are only going up against signatures, and the thing that everybody loves to scream about is that VirusTotal shares those results with the vendors. So if it gets flagged by one vendor but not some of the others, VirusTotal will redistribute that information to all the vendors so that they can sig the same thing.
Why this doesn’t actually matter for our process is that this is all strictly proof of concept, and if we can’t survive this then our technique is broken anyways because we are doing the same thing everybody has been doing.
Antivirus evasion, malware – all of this is sort of an arms race. We come up with something new to get past antivirus, and antivirus finds a way to detect it. We find something new and we just keep going in this pattern back and forth and nothing really breaks the cycle. So what I am looking for is some way that we can break that cycle and do something that really just gets us beyond doing this same routine, the same song and dance over and over again.So the first question you have to ask is: “Where are these detections coming from?” Well, the one we have been seeing for years and telling people is the biggest problem is the executable template. When we build an EXE in Metasploit Framework or Pro today, we have pre-built executables that are used by default. It shows our payload in there, takes that executable, sends it to the file system and it just runs.
Well, like I said, you can upload those templates with no payload whatsoever and it still detects it as malicious on 42 vendors, which is really hilarious because our default template in Metasploit is the ApacheBench software which is a completely legitimate tool. The Apache guys probably love us for that one.
The next place it is getting caught is the stager. Reverse_tcp is an incredibly recognizable piece of shellcode at this point and it contains a common piece of shellcode called BlockAPI that was written by Stephen Fewer, and most shellcoders use BlockAPI.
What BlockAPI is for – is because when you are doing a memory corruption exploit you don’t know what the addresses of any of the Windows API functions are. You need a way to call those functions reliably and get the addresses for them. So BlockAPI goes through and actually tries to find a way to call those functions without already knowing what the addresses are. It is great piece of shell code, it is highly optimized, it is very small, but the problem is everybody uses it, so every AV vendor knows to look for it.
One of the things that I thought might be a problem is creating RWX memory. Creating executable memory at runtime sounds a little suspicious, right? I mean it is not that easy to think of a scenario where a legitimate program at runtime is going to create a whole new section of memory and mark it as executable. Why would you do that?
The last possible place that we are getting flagged is the encoder, and this is going to be a little important later but I am going to say this upfront – encoders do not evade antivirus, once again – encoders do not evade antivirus. If you come into the Metasploit channel and say: “My payload is getting flagged, I don’t understand, I ran it through an encoder,” – I’m going to hurt you.
Read previous: AV Evasion: Lessons Learned