# Hacking Tube

## DEFCON CTF 2017 Quals -- peROPdo

Category: Potent Pwnables

32 bit ELF, static link, stripped, NX enabled, No PIE & canary.

The program is a "rolling dice" program. First we input our name, then the program will ask us how many dice would we like to roll. After we input a number, the program will start generating some random data, then store them on the stack memory. The program will then print out data[i] % 6 + 1, which represent the numbers we roll in this round.

There're two vulnerabilities in the program. First it use scanf("%s", name) to read our name, which lead to buffer overflow in the name buffer. Then, if we input a number that is larger than 23, the data that program generated will overflow the data[i] buffer and thus overwrite the return address ( it will be a random data though ).

Since the binary was stripped, I wasn't sure which algorithm the program used for randomizing, the only thing I knew is that the algorithm will use our name to generate the random data. At that moment, I thought it was just some self-implement function ( which is NOT correct, we'll get into that later).

And so I thought "Hmmm, maybe I could use some symbolic execution tool to calculate the address I want to return, and do the ROP attack". This was such a huge mistake, since I'm not familiar with any of the symbolic execution tools -- angr, Triton, not to mention the fresh out manticore. Even worse, all of the tool failed to calculate the address -- Triton and manticore couldn't even execute the program, it just crashed :(

After wasting lots of time with those symbolic execution tools, I decided to try something different -- the first vulnerability: overflowing the name buffer. And the result was encouraging -- since I found that I could hijack the control flow by using the call reg and the call [reg+offset] gadget ( we can control the content of several registers ). It seems that there're some FILE* pointer behind the name buffer, so we can exploit the service by abusing the FILE structure ( we can't control the function parameters though).

Here I chose to use the second gadget ( call [reg+offset] ), since when the program execute to that line of code, its second parameter will be the FILE* pointer of stdout. I control the eip and jump to the middle of the main function:

This will make the program store the %s string to the first parameter, then call the scanf function, making the program calling scanf("%s", stdout) -- and thus we can control the content of stdout !

By crafting stdout, we can actually hijack the control flow, while having the first parameter controlled. This allowed us to do some advanced ROP attack. Here's what I did after I controlled the eip:

1. Jump to xchg esp, eax gadget, migrate the stack to stdout (which now controlled by us)
2. Use add esp, offset to skip the uncontrollable member data in stdout
3. Since it's a static linked binary, it's easy for us to find some gadgets and do the open/read/write syscall, making the service print out the flag of the challenge. (The execve syscall seems to be filtered out in this challenge)

Final exploit:

flag: Thanks to Kenshoto for the inspiration! 5fbb34920c457b2e0855a174b8de3ebc

Later did I know (thanks to teammate Isaac) that there's a thing call FLIRT in IDA Pro, which can help the user identify the function call in libc. All we need to do is download a FLIRT signature database from github ( here's the DB I used for this challenge ), and use FILE --> Load File --> FLIRT signature file to load the database. IDA will then identify the function name, making the reverse engineering less painful. By using this technique, we'll be able to identify some libc function, even the location of stdout.

And that's when I found that the "self-implement random" function is actually just srand() & rand() in libc. According to meh from HITCON, you can just brute-force the desired return address. Moreover, because the name buffer address is right under the return address, so you can just use pop esp; ret to migrate the stack into name buffer, and do the ROP attack. Guess I still got a lot of shit to learn :/