Continuing to elaborate on ways to circumvent antivirus detection, David Maloney dissects code generation and Ghost-Writing techniques in this regard.One of my co-workers said to me: “What about doing code generation, what if you never put your payload in the executable at all; instead, you have your executable generate the code for your payload?” Basically, the way this works (see right-hand image) is you take a register, any register, in this case I use EAX; zero it out; you encode your payload to a series of 32-bit integers which you have to align the payload first because a lot them aren’t aligned properly for that. But you zero out a register; you set ESP which is your stack pointer, it tells you where the top of the stack is. You take ESP and you point it into executable memory to where your code is, to some placeholder function that you have that has instructions you don’t care about. And then you start performing math operations.
You know that for your first 32-bit integer which will be the last set of bytes in your payload, and you add EAX that number. Then you push it to the stack, only now your stack is in executable memory. Then you look at your next 32-bit integer and you take the difference between that and the value in EAX, and you do a math operation to get EAX to equal that next byte. You keep doing that over and over, pushing each byte to the stack.So our payload is never actually a part of the executable, it’s never in memory until the end of execution, and it just builds that code on the fly. That seems like it should work, right, your payloads are not there to be seen. I see people shaking their head… And then we ‘jmp esp’ at the end of course.
Nope! Totally didn’t work (see left-hand image). This kind of blew my mind because I’ve still got in my head this idea that signatures are still a big part of antivirus evasion. That’s obviously not true.We are still doing this, still hiding, because what we are doing still looks suspicious. We are moving the stack into executable memory and then we are writing stuff there. What program does that? I mean, what legitimate developer uses that as a programming technique? You show me the developer that does that and I will show you a shitty developer. Ok, let’s talk about Ghost-Writing, oh sorry, not that Ghost-Writing (see left-hand image), 80’s reference, hopefully some people get it. Ghost-Writing (see right-hand image) has been a big thing that people have been talking about, especially the past two years. Some guys did a really good talk on it last year, I believe. And there have been a bunch of blog posts on it this year. Ghost-Writing is basically this idea of – you take your payload or whatever assembly that you’ve got running, and you go through it and you say: “What can I replace this instruction with? Ok, I have increment EAX. Well, what if I do something else that has the same effect?”
In our case it may be multiple instructions to replace a single instruction. One of the big problems with Metasploit payloads when we are talking about dropping to the file system is that they are written for memory corruption, which means they have a bunch of broken assumptions when you talk about dropping to the file system. One of which is that the size of the payload is really important. So we optimize everything to be the fewest bytes possible.
We don’t have that concern when we are dropping in an executable. We have as much space as we want. So let’s replace all these instructions with multiple instructions that end up doing the same thing but don’t look like the code that you’re expecting to see.So, what do you think, is this blending in or is this still hiding? It’s still hiding (see left-hand image). And appropriately, Ghost-Writing with fuzzy NOPs, because why not, still gets us nowhere. And this is really funny to me because I have seen a lot of people saying: “This is the solution. This is it right here, you do assembly Ghost-Writing and you will never get caught by antivirus!” That’s obviously not true.
Again, we are hiding the bad, we are trying to hide the obviously heinous thing that we are doing in memory rather than trying to make it look like a legitimate program. So, pretty much all these techniques have been hiding: obfuscation, encoding, doing code generation tricks – they are all things that are the guy standing in the alleyway out of sight. Yes, he doesn’t get seen from the street but as soon as somebody walks past the right way, they are going to be a little weirded out by that guy in a hoodie just standing in an alleyway somewhere.What we need to do is we need to camouflage ourselves (see right-hand image). We need to look so close to a legitimate executable that even if antivirus does figure out what we are – they can’t flag us because flagging us would mean that they would risk flagging legitimate programs. Because if they start doing that they are broken, nobody will buy their stuff if the legitimate programs start getting killed by antivirus. So we want to get right up next to the tools that everybody uses every day and make ourselves indistinguishable from them. Then we can just look at AV and say: “Come at me bro!” These are the problems we have talked about (see left-hand image). Our templates get flagged, the stager gets flagged, encoders get flagged, and our very behaviour with these techniques is just completely suspicious. No legitimate program would do any of these things. So, how do we get around the executable template problem now? Well, in Metasploit Pro what we have done and anyone can do this on their own if they want to take the time for it – is we dynamically generate those templates now (see right-hand image). We use Metasm to write EXEs on the fly. We generate code paths that are completely random and dynamic, we create random variables and use them to do math operations or whatever so that the memory layout of the executable is different every single time we create it, the execution path is different every single time we create it. There is no way to create a signature like that. You sig one of them, you are not going to catch the next one or the next one and so forth. So, that one is really easy to get around. The encoders – just don’t use them, that’s all this one breaks down to, don’t use encoders when you are dropping to the file system, it’s not worth it, it gets you nothing (see left-hand image). The stager (see right-hand image). Like I said, all of our shellcode was originally designed for memory corruption exploits, doing a buffer overflow. They are highly optimized, smallest bytecodes possible. Everything uses BlockAPI because we don’t know where our API functions are, right?
Well, if we are generating an executable, we are a developer at that point. We can use the same techniques that developers use to do linking, and we can get those functions. Payloads from Metasploit, as they exist for the stager, are really not necessary and dangerous for dropping to the file system, we are using them in a way they were never intended to. So, what’s the solution for that?
Read previous: AV Evasion 4: Encoders and Fuzzy NOPs Fail
Read previous: AV Evasion 6: Best-Performing Tactics