# 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.