DCTF Quals 2023 - Awesome One
AwesomeOne was a challenge at the D-CTF Qualifiers from 2023.
This was a very simple reverse engineering challenge which I used as a reason to install Ghidra again :)
The challenge
For this challenge, we got a binary that was asking for a password and then returned some messages & some numbers.
If I ran strings on it, I could see all their funny messages.
It looks like the program just picks one at random.
Some reverse engineering
I opened the binary in Ghidra and looked at the output of the decompiler.
The program asks the user to input a password (the flag), and then checks if it is the correct one by using the check_password function.
By taking a look at the check_password function, I could see that the flag is stored in a variable: enc_flag.
The flag is not plaintext: it is probably encoded or encrypted somehow.
And I could also see some kind of XOR operation there. Some quick analysis of that operation:
The program was XOR-ing between the flag length, the user input length and the current character from the user input.
Then, it makes a bitwise OR between the values obtained like that for each character.
The two lengths should be equal when you input the flag, so that would go away (X XOR X = 0).
After that, we have a bitwise OR between all the characters in the user input.
This probably leads to all the bits in the result being set to 1 in the end (for a large input).
So this is probably not an useful operation. Let’s look at the the enc_flag variable.
That contains an address (remember that in C string variables are just pointers to the beginning of a char array!!!).
By looking at that address, I could notice an array of characters. Those don’t look printable so there is some encoding going on here.
I copied the value of those bytes by selecting them, right clicking and then using ‘Copy Special’ (if you are not familiar with Ghidra :) )
And chose to copy the byte string.
I got something that looks like this.
I can exclude the last character (00) since that’s just the null terminator for this string.
I wanted to decode the string so I tried some stuff in CyberChef.
As expected, just using ‘From Hex’ doesn’t result in anything useful or readable.
However, if we try using the ‘XOR Brute Force’ operation.
I just set the crib to ‘CTF’ since I knew the flag format and for key=45 I got a valid flag.
Why XOR?
The ‘result’ value obtained obtained in check_password seemed to be garbage to me.
However, I was thinking that if the first OR was replaced with another XOR, the value might’ve resembled some kind of hash (a XOR between all the characters of the input).
So XOR was among the very first things that I thought of for transforming this string into something usable.
Flag obtained: CTF{fc3a41a577ff10786a2fdbfcad18ef47ea78d426a47d097a49e3803f7e9c0e96}