BreizhCTF 2019: Roxog
Challenge: roxog md5sum : 25adcd4f3a2b281ec5b43e0f94236246
A Go binary, flag xored with static int
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 :).
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 :
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
The function is loading data that look like a cipher
And finally there is a loop with a xor by
At this point, I made the assumption that the data loaded by the function was xored by
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
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.
Let’s fire up GDB :
Now break at
0x40102F where we load the cipher
And step few instructions to see the loaded data in
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 :
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 :)