First the challenge gave us a binary file (ELF for Intel-386). But we can't execute it, cause we don't have the required shared library "libchallengeresponse.so". So we will have to launch IDA Pro to see what's going on within the program.
After analyzing the program ( praise the powerful F5 key! ) , I collected the following information:
As we can see, the main function will read a byte from the user input, and do the
v1 will hold the result, and a
switch-case condition will decide which function to run next, base on
So basically, we can summarize that the main function will only accept 3 kinds of input:
0xA0 ~ 0xAF,
0xE0 ~ 0xEF and
0x80 ~ 0x8F. Now let's take a good look at those functions.
functionA, we found a
bufferA, which start from a specific address.
functionA will take the original input (a byte value) as the parameter, extract its last 4 bit, take it as the offset from
bufferA and calculate the position's address. Then,
v2 will store a 4 bytes value, start from the new address in
bufferA. At last the function will print out 4 char (= 4 byte) which was stored in
Note that if the offset is
0x1, the new address will start from
bufferA + 4, if the offset is
0x2, the new address will start from
bufferA + 8...and so on (basic knowledge of pointer).
functionB, we found
bufferC , both start from a specific address. Like
functionB also take the original input (a byte value) as the parameter, extract its last 4 bit and take it as a
offset. But there's a slight difference. In
v4 will store a 4 bytes value, start from the new position in
bufferB, while another variable
v5 also read a 4 bytes value from the user input and hold its value. Then, the function will compare these two value, if they are the same, it will store value
1 in bufferC, the position is also base on the
So, if the user input is
offset will store the value
v4 will store the value
bufferB + 16 ~
bufferB + 20,
v5 will read another 4 bytes from user input. If
v4 == v5, then
bufferC will store the value
functionC is quite simple. It just calculate the factorial of all the values stored in
bufferC. If the result isn't
0, it will print out the flag, or else it will terminate the program.
So, to sum up all the functions mentioned previously and how are we going to exploit:
functionA to get all the values stored in
bufferB (use IDA pro to check the offset between
bufferB, the offset is
functionB to overwrite the value in
bufferC, in order to pass the checking function
functionC to get the flag
But here is the tricky part: the values stored in
bufferB are not fixed.
So, I finally decided to write a python script to solve the challenge.