Protostar - stack6
Moving on to the next challenge. Here’s where things get interesting. This challenge is actually based on a security mechanism(not really but similar), it basically won’t execute anything on the stack, so how do we exploit this binary? First have a look at the code:
Let’s take a look at the “getpath()” method. If you’ve done the previous challenges this is simple, well almost. With one catch. The return address is restricted. Let’s take a closer look at what this means…
Using this command we can see the layout of how the memory is used for the process. From the C code we see that we can’t return to any address starting with “0xbf”. From the map above we can see that this is roughly where the stack resides. What this means is that executing instructions from the stack is a no go.
So, now what? We can’t return to any address on the stack, injecting code is useless. We will now ‘try harder’. After a little investigation I came across return oriented programming or ROP for short. What is ROP? ROP is a way of constructing your payload by using existing code present. So instead of using our stack address to return to, We use an existing address to return to. What we’re essentially doing is creating a fake stack frame. It looks kind of like this.
In order to call an existing function we need to follow this layout as it is a convention. We’re going to make use of the C standard library functions to craft our exploit. This is a modified ROP known as ret2libc. So basically we’ll be making use of C existing library functions.
First things first, let’s find the offset.
Use this as a pattern to find the offset.
So once that’s done we need to go function hunting. We need 2 function addresses, one “system()” and the other “exit()”. Note that “exit()” is here to satisfy the calling convention as our return pointer. It can be any function, but this goes for a much cleaner way to do things.
We can get those two fairly trivially using gdb.
So those are the addresses we require, note them down somewhere, we’ll use them in our exploit. But wait, there’s more we need a way to tell “system()” what parameters we’ve given it. We can do this by following the calling convention. But since we can’t store anything on the stack, we need another way. Why not use libc itself again, since we’re ret2libc’ing anyways. What we need is an address to a string which says “/bin/sh”, for a way to get “system()” to spawn a shell for us.
Here’s how we do that…(assuming we know where libc is located)
Now this address is actually the offset. So we need to add this to the beginning of the address at which libc is loaded. From the memory map way above, we see that it starts at “0xb7e97000” so the actual location of the string will be “0xb7e97000 + 0x11f3bf”. This will be important for our exploit.
Now we can finally craft our exploit…
Exploiting in 3…2…1…using cat to hold the input.
And there you have it. Another fun challenge, this time by reusing existing resources by ROP. I was pretty amused by this, I hope that you are too. Until next time, cheers!
P.S. The exploit-exercises website is most probably dead.