Wargames Vietnam CTF - Bin150
Monday, August 12, 2013 | Author: Deep Flash
In this challenge, we are given an ELF 32-bit binary for 80386 platform.

We need to find the serial corresponding to the username: MARIO-HACKER-IS-HERE

Here are some details about the file given:



 
Let us analyze the main() subroutine with gdb:



 The important section of the code is here:



0x804a03c points to the username: MARIO-HACKER-IS-HERE

It reads a byte from the username, checks if it is not 0. If it is not 0 then it passes that to the subroutine, gate()

After returning from the gate() subroutine, it will add the result to the value pointed to by [esp+28].

Once all the characters from the username are read, it will compare the result with 0x109c2. They should be equal.

The gate() subroutine will perform calculation on this byte and based on it, call a particular switch case.

Below is the section of code in the gate() subroutine for this:



There are a total of 11 cases. The value in edx is the result of calculation on the byte read from the username. Then, it calls a specific switch case.

Since, the username is fixed, so the sequence in which the switch cases are called is also fixed.

This sequence is:  7, 5, 3, 9, 5, 5, 5, 2, 5, 3, 5, 9, 2, 9

In each case, it will read the bytes from the serial, then call either of the functions, mul(), sub(), mod(), div()

The sequence is:

div, mul,  mod, sub, mul, mul, mul, mul, mul, mod, mul, sub, mul, sub

Based on analysis of the switch case subroutines, the equation is:

result = div(key[0], 0x31) + mul(reg[1], reg[2]) + mod(key[3], 0x31) + sub(key[4], key[4]) + mul(reg[1], reg[2]) + mul(reg[1], reg[2]) + mul(reg[1], reg[2]) + mul(key[11], 0x52) + mul(reg[1], reg[2]) + mod(key[14], 0x31) + mul(reg[1], reg[2]) + sub(key[17], key[17]) + mul(key[18], 0x52) + sub(key[19], key[19])

in switch case, 9, the subroutine will return 0 since it performs, sub(key[i], key[i])

also, we know that the flag should be in the format: mario_xxxxxxxxxxx

the length of the serial == length of the username

also, in switch case 5, the multiplication operation is not performed on the current byte read from the serial, but the previous values loaded in reg1 and reg2.



The first part of the serial, "mario_" is fixed.

The value of result corresponding to this is: 0x14e6

so, we need to find the remaining part of the serial such that result == (0x109c2 - 0x14e6) = 0xf4dc

also, if you check the equation above, the next 3 multiplication operations use the values in reg1 and reg2 that are the bytes corresponding to key[4], 0x6f

so, we need to find: mario_{key}

and the reduced equation is:

mul(key[5], 0x52) + mul(key[5], 0x52) + mod(key[8], 0x31) + mul(key[8], 0x31) + mul(key[12], 0x52) == 0x6479

Let us represent, key[5] as a, key[8] as b and key[12] as c.

so, the equation becomes:

mul(a, 0x52) + mul(a, 0x52) + mod(b, 0x31) + mul(b, 0x31) + mul(c, 0x52) == 0x6479

I could not find the values of a, b and c such that above equation is satisfied, however, I found the closest match by writing the following script:



output:



the possible values of serial:

mario_xxxxxaxxlxxx7x
mario_xxxxxbxxlxxx5x
mario_xxxxxcxxlxxx3x
mario_xxxxxdxxlxxx1x

I am able to get the output as, 0x109c1:



I will try some other combinations of values of a, b and c again :)