BreizhCTF 2019: Roxog
Challenge details
Event | Challenge | Category | Points | Solves |
---|---|---|---|---|
BreizhCTF 2019 | Roxog | Reverse | 100 | ? |
Challenge: roxog md5sum : 25adcd4f3a2b281ec5b43e0f94236246
TL;DR
A Go binary, flag xored with static int
Methodology
Recon with r2
First we fire up r2 : r2 -A ./roxog
It take quite a long time, we can first assume it’s staticly compiled
Then we search the main function (afl
for listing function and ~main
to make a grep on this list) :
The syntax look alike a Go binary, main.main
is the main function in Go binaries.
Since it’s Go, I prefer IDA to reverse it. So let’s fire up IDA to make serious business :).
IDA Part
When looking at main_main
, we don’t see any obvious comparison, except one that compare args, we can assume it’s the good way to follow since there is an os_Exit call in the box before.
When we have enough args and we jump below a strange function is called : runtime_text
Let’s see what’s hiding in this function.
In this function we can see some interesting things :
It seems that the initial name of this function was
main.roxgo
The function is loading data that look like a cipher
And finally there is a loop with a xor by
0x7f
Hypothesis
At this point, I made the assumption that the data loaded by the function was xored by 0x7F
.
It cost almost no time to test this assumption and if it’s true, I will save a lot of time.
So let’s follow this hypothesis.
To have the data I go with radare again, data is at 0x4AFE80
we just have to tell the length and the address (here the length is totally random we just need a quick test) : ps 300 @0x4AFE80
Then let’s script it :
potential_cipher = open("out").read()
out = ""
for i in potential_cipher:
out += chr((0x7f ^ ord(i)) & 0xff)
print(out)
Looks like we are on the right path :)
The funny thing with Go, is that String are not like C char*
so let’s find another way to dump this cipher.
GDB part
Let’s fire up GDB :
Now break at 0x40102F
where we load the cipher
And step few instructions to see the loaded data in rax
(n
to step one instruction):
Now let’s dump rax data with dump memory out $rax $rax+30
where out
is the output file, $rax
the start and $rax+30
the stop address
And execute again our Python script since my out file is the same that I had before ;)
Ok we have the end o the flag … Let’s dump a little bit before :
And execute our script :
Conclusion
Try to make assumption when you’re reversing a CTF challenge, it can save you many time. And look for xor, many reverser likes to use xor in their challenges :)
Flag
BREIZHCTF{d0_y0u_Kn0w_7h47_m4nY_pr0j3kt5_4r3_wr1773n_in_GO?!_g0ph3r_rul35_t3h_w0r1d_0x7f}
@Areizen