Hacking Series Part 8
Category: binary exploitation
We are given a binary called “seedspring” that essentially simulates a guessing game. There are 30 levels to the game, on each level you need to guess the correct randomly generated number to advance to the next level. After opening the binary in IDA, you immediately see a large amount of calls to puts
, which print the following banner when you first run the program.
The assembly that needs inspection really begins at loc_975
, where a loop is initiated that uses a counter from 1 to 30 (1Eh). If the counter (stored in [ebp-0Ch]
) is less than or equal to 30, execution jumps to loc_8B7
, and if it is greater than 30, it continues execution to the next instruction. This also means you have won the game, and if the program is run on the server, you will get the flag.
The only thing that needs to be done is get the seed used in the srand
function, then generate the next 30 random numbers using that same seed. These random numbers will the same that the program will generate (with rand
), since the seed used will be the same.
Before the loop is initiated, there are two functions that we need to pay attention to in order to see how the seed is generated, the first is time
and the second is the one that was previously mentioned, srand
. From the looks of it, the time used when the program is run is used as the seed, since the result of time
is stored in eax
, then used as a parameter to srand
.
To verify that this is correct, I opened the binary in gdb and set a breakpoint at the push eax
instruction to see what was inside eax before srand
was called. I recognized that the time was stored in eax as expected.
Obviously, the seed will change with every run of the program, but since we know exactly what is happening, we can replicate the program with our own C code. In an online C compiler, I made a call to srand
with the current time, then made 30 calls to rand
in a loop and printed these numbers. In the assembly, a bitwise and
operation is preformed on each result of rand with the number 15, which also needs to be replicated in the C code.
The seed needs to be changed accordingly, but can be replaced with the time
function. You would have to account for a delay of a second or two, since it would be a few seconds between starting the program on the server and running the above code, but you just need to get the delay right once. After completing level 30, I got the flag.
picoCTF{pseudo_random_number_generator_not_so_random_248ec303}