Level 3, one of my favorites! As with the previous level, we started a binary on the vm with socat. This time we find a random number game.. As usual we start fuzzing..(string format, buffer overflow etc.) but after some time we haven’t found anything. Time to look closer at the binary.. Once loaded into IDA I first spotted a string format vulnerability. The vulnerability only occurred when strtol(input) is bigger than the random number. Strtol interpreters the string as an int, discarding any invalid characters, thats why %x as input didn’t trigger the vulnerability. We have to input something like 99%x to trigger the code path that has the string format vulnerability (Little troll of c0ne 🙂 ).
But there is more! c0ne hinted there is a second vulnerability.. Digging back into the binary I found the buffer overflow vulnerability in the readline function. Why didn’t I find that one earlier?! Now I also understood why he included the string format vulnerability: stack cookies! The binary is compiled with NX(Non executable stack) and stack cookies/canaries. With the string format vulnerability we can first leak the stack cookie that we can use in the buffer overflow.
I began setting breakpoints in GDB, looking up the canary and comparing it with the memory I dumped using the string format vulnerability. Once I finally found the ‘stack index’ of the canary I started working on the buffer overflow in the readline fuction(). ASLR is on, the binary is statically compiled and we have a non executable stack so a ROP chain is the way to go! Because the binary is statically compiled we can’t do an execve or system call because those functions are just not present. On the other hand, enough ROP gadgets are available! I use ropeme to search for useful gadgets and begin listing some interesting ones. Eventually I stumbled upon “ïnt 0x80; return;” and I wonder if we could do a direct syscall to execve.. (this is what a lot of shellcode actually does!). I started implementing a nice mem copy function in Python to automate all of the mem copy operations in the ROP chain. After I was able to set everything up that was needed for the syscall in the writeable bss section I finished the ROP chain by putting the arguments for the syscall in the right registers and voila! Worked beautifully! Next thing I did was launch the exploit against the Pandora’s Box VM(I was testing locally) and….
What happened with our leaked stack cookie?!? After poking around and trying to attach gdb to the process instead of launching it directly from GDB I noticed the stack cookie was on a different ‘stack index’ when launched under GDB. No problem! We looked up the new stack index and this time we successfully exploited level 3 😀 Yes!
And of course our solution should not be missing: