TCTF 2019 - Elements (107pt)
floating point reversing
March 25, 2019
reversing
Elements (107pt)
Reversing
Description: none
Files: Elements
Solution:
A first look at the binary shows that it reads some user input string and processes it in some complex way involving floating point operations. Embedded in a bunch of conditionals we see:
puts("Congratz, input is your flag");
So we need to figure out what input will reach this point.
At the start we find an fgets
call to read input from stdin. Then it exits early if the length of the flag is not 0x2c
or doesn’t start with flag{
and end with }
. Then it takes the part inside the curly brackets and splits it by the token -
. If any of these pieces is not 12
characters long, it exits.
Then we see a portion of the code loop over the characters to “unhexlify” the string.
At this point we know the flag is of the format: flag{%12x-%12x-%12x}
.
Additionally, the first of the three numbers is compared against the value: 0x391bc2164f0a
so we can further constrain the flag to: flag{391bc2164f0a-%12x-%12x}
.
In the next part, the three numbers are converted to their corresponding floating point representation and loaded into xmm3
, xmm4
and xmm5
respectively. (I will refer to these numbers as a
, b
and c
)
The binary then performs the following checks against these three numbers (using floating point operations) and fails if any of them do not pass:
a < b < c
a + b > c
sqrt(4*a^2*b^2 - (a^2+b^2-c^2)^2)/(2*(a+b+c)) == 19400354808065.543
abc/sqrt(4*a^2*b^2 - (a^2+b^2-c^2)^2) == 47770539528273.91
The equivalencies are performed by subtracting the right hand side and checking if the result is 0 +/- 0.00001
.
We can obtain a solution by plugging these equations into wolfram alpha and hexlifying the values of b
and c
into the flag.