I’ve been having some fun over the past weekend getting my chops back up to speed with some wargames at overthewire.org. So far i’m up to Vortex 9, and it’s been a bunch of fun :D.
Instead of going back and documenting 0-7 (which you can look up elsewhere), i’m going to start documenting from 8+ (which is nowhere on the web). Here is the work i’ve done :]
First things first we need hacking music. I recommend this series I wrote a while ago:
Ok, this is a reverse engineering challenge, so lets download a copy of vortex8.bin and boot up IDA to take a look at what’s going on.
We find the following execution
1. Start a new thread
2. Drop permissions from Vortex9 to Vortex8.
The only thing this new thread does is a really silly while(1) loop.
So this thread is just gonna print “0” to the screen every second. I think I see where this is going. Lets keep the fact that we’re calling “sleep” in mind.
The next thing the main thread does is make another call, which ends up providing us an opportunity to overflow a buffer..
So overrun this 1032 byte buffer and we’ll hit the stored stack pointer & return address. Easy enough… but we’ve got an issue
We can’t just straight execute from the stack, because we’ll be executing at “Level 8” permissions. Instead, we need to get the thread running at “Level 9” permissions to run code that we put in the buffer.
So the other function makes a couple function calls, including printf and sleep. Why don’t we try to overwrite the sleep function offset in the Global Offset Table, and get that other thread to start executing from this one’s stack (neat!). We can do this because multiple threads in a single process share linear memory space. If we had opened a separate process, we would have needed to find a way to open a remote thread/memory and write to it. Good thing we don’t have to worry about that.
So first thing we should do is use gdb to get the GOT entry for sleep
We’re going to overwrite 0x0804a008 to point to our shellcode on the stack. To save time and space, my shellcode resides at 0xFFFFD26E. You can use gdb to print out the value of ESP when you’re inside the unsecurecode function. From there, just use the size of your shellcode to calculate exactly where it’s going to start (and how many nops you’ll need).
Lets write the assembly that’s going to replace this GOT entry and assemble it. And then this quick little python function to display it on the screen for me to copy/paste (I use this for any thing i have to assemble & print, it’s a handy little tool imo)
cool. We’ve got everything we need to make our final script
I glossed over a few things. So lets touch on that:
1. NO \x00 ALLOWED! Your entire payload CANNOT have a \x00 in it (until the end). strcopy() terminates when it hits a null byte, so you must ensure anything you assemble does NOT have a null byte.
2. You need to find your stack pointer and base pointer. If you don’t realign the stack basepointer, when you RET onto the stack you’re gonna throw segfaults. Make sure you overrun the stored basepointer with some place in memory that’s writable.
3. We’re going to execute the code to overwrite the GOT entry for sleep with the pointer for our shellcode on the stack, and then we’re going to \xEB\xFE in order to make that thread spin. Remember, if we let the main thread die, then the program will terminate before we get to do anything with our shell in the other thread!
4. Now that we’ve overwritten the entry and started spinning, the other thread in the while loop should take care of the rest. The next time the while loop comes around to call the “sleep” function, we should get execution of our shellcode.
lets try it out
NEAT!