This is one of my favorite challenges. We actually get to do something useful here. Our task is to execute shellcode.
Shellcode is nothing but a sequence of bytes, which when executed does some task. Note that this only works if the stack is executable.
This is true for older machines, however newer ones mitigate this vulnerability my making the stack non executable. We don’t have to worry much about that.
So here’s the code.
Nothing useful overhere, except the fact that we have an exploitable gets() function. So our choice of attack is a buffer overflow. We know from the previous post, that we can overflow into the EIP. Thus controlling the codeflow.
Once we can do that, it’s just a matter of redirecting control to our ‘injected’ shell code. First things first. Let’s get the offset of the EIP. I’m using pwntools to generate the offset string.
Finding “0x61616174” in the offset string we find the location of the EIP at 76 bytes. So our address to our shellcode goes after 76 bytes of padding.
Before we proceed let’s take a look at the stack and figure out where to place our shell code.
We can probably choose anyone of these addresses, let’s try the first one 0xbffff7b0.
Below is the exploit script code.
Now let’s run this and see what happens.
Oh oh!. Something’s not right, we’re getting an illegal instruction error. Let’s take a look at it in the debugger.
We find something even more funny here, it works perfectly fine in the debugger.
This actually bugged me for quite some time. I found a solution to this in the reddit thread here.
What happens is that when you execute a program, the OS even pushes the environment variables onto the stack.
Now when we run the executable outside gdb, the environment is different, and hence the shellcode gets misaligned.
To counter this we can use something called as a NOP slide. NOP is short for no instruction, which will basically do nothing.
The idea is that you set your EIP to an arbitrary address which you hope will land on the NOP slide.
We place our shellcode after the NOP slide, so when the NOPs are done executing, our shellcode is executed.
There is a little trick to choosing this arbitrary address and length of NOP slides, they should be a multiple of 4, else your shellcode will be misaligned.
This is what is happening to us outside gdb, our shellcode is getting misaligned, so let’s fix it.
The below exploit is with a little trial and error, but you should get the idea.
Let’s run it:
Ok, so no error this time. This begs the question, how do we use the shell, since it exits as soon as it is created.
The reason is that as the input stream closes the shell also exits. So we need a way to hold the input stream.
After digging around a little I came across this stackoverflow post.
So using one of those techniques…
Owned! We finally managed to get a shell with root privilages. I hope this gives you a taste of privilage escalation. This was by far the most fun exercise I’ve done. Hope you enjoyed this too :)