Writeup: Plaid CTF 2020 - Reee
Information
- category : reverse
- points : 150
Description
1 file: reee.bin
Writeup
We have a 64 bit elf binary, let’s start analyzing it with radare2:
1 | $ r2 reee.bin |
It’s a stripped binary and it’s not a PIE executable.
This it the main graph:
And this is the main decompiled:
1 | void main(char *argc, char **argv) |
From the decompiled version we can deduce 3 things:
- The program take in input an argument (flag).
- The argument is passed to the function fcn.004006e5.
- The function fcn.004006e5 is modified in the nested while using the
function fcn.00400526.
In fact if we check the asm of fcn.004006e5 is messed up:
1 | 60: fcn.004006e5 (int64_t arg2, uint32_t arg4, int64_t arg_58ae7f6ah); |
And it’s full of invalid instructions.
We can try to check fcn.00400526:
1 | int32_t fcn.00400526(int64_t arg1) |
This function is not impossible to understand, but we can take another approach.
We can set a breakpoint in:
1 | iVar2 = fcn.004006e5(argc, (int64_t)arg2, placeholder_2, in_ECX); |
And simply debug the binary
1 | [0x0040064e]> db 0x004006db |
Now the function is more clear. We can also decompile the function:
1 | [0x004006e5]> pdg |
The asm code of the function 0x00400702 is long and I will not post it, but
we can easily decompile it. Since this function is not define on radare2, we
need to define it. In visual mode seek to 0x00400702 and press df
, and then pdg
:
1 | bool fcn.00400702(int64_t arg1) |
This code is very clear now. fcn.00400702 applies to our input argv[1]
a function:
xor every character with the precedent one and repeat the operation 0x539 times.
At the end the function checks that the result is equal to the array in 0x4008eb.
We can dump the content of 0x4008eb:
1 | [0x0040071a]> pxj 100@0x4008eb |
Now we have one problem, we don’t know the length of the flag.
We can:
- Bruteforce it.
- Guess it.
- Doing some math.
We did it with bruteforce but we can guess that is long until the first null terminator\x00
in the output of pxj 100@0x4008eb
.
Now it’s time to compute the flag, I personally chose to use z3
.
Exploit
1 | from z3 import * |
Flag
pctf{ok_nothing_too_fancy_there!}
Fails
Me and @sen tried to solve the challenge using instructions counting with frida,
but we failed since this challenge is not vulnerable to that type of attack.