CTFlearn: Ramada
Ramada is an easy reversing challenge from ctflearn. It is one of those challenges that is both easy and kinda hard at the same time. I got really stuck because the script I wrote to reverse some operations didn’t round the integers correctly, it would have been easy otherwise.
When we run the challenge we see the following:
When we run it again with an argument to match the usage Ramada CTFlearn{kernel}
we get:
Open it now with ghidra to analyse the source. Open the main function in the Decompiler:
In the source at line 49 we find the expected length of the flag:
sVar4 = strlen((char *)__s);
...
if (sVar4 == 0x1f) {
Converting sVar4 0x1f
to an integer is 31
The CTFlearn{}
part of the flag is 31 - 10 = 21
Generate a string of length 21 to test it:
crazyeights@es-base:~$ python3 -c "print('CTFlearn{'+'A'*21+'}')"
CTFlearn{AAAAAAAAAAAAAAAAAAAAA}
When we run it with the correct length flag we get:
In the main function in the decompiler we can see that the function CheckFlag is called:
iVar3 = CheckFlag((char *)aiStack104);
CheckFlag()
is called with only the so-called kernel part of the flag as input, meaning it doesn’t include the CTFlearn{}
part.
Next we check the contents of the CheckFlag function:
In CheckFlag()
function it loops through the user input, iVar2
for each char in the string it is cast to int, and cubes it, and then compared to the corresponding int in the data
array. We can assume that the flag is stored in data
Checking out the contents of data:
Since we know that iVar2 * iVar2 * iVar2
is equal to data if the user enters the correct flag. We can write a program that takes each entry in data and reverses the cube operation (cube root) :
import numpy as np
data = [0x13693, 0x6b2c0, 0x11a9f9, 0x157000, 0x1cb91, 0x1bb528, 0x1bb528, 0xded21, 0x144f38, 0xfb89d, 0x169b48, 0xd151f, 0x8b98b, 0x17d140, 0xded21, 0x1338c0, 0x1338c0, 0x11a9f9, 0x1b000, 0x144f38, 0x1734eb]
s = ""
for d in data:
s+=str(hex(round(np.cbrt(int(d)))))[2:]+" "
print(s)
We get the following (with each entry being in hex):
When we get ascii representation instead we get:
The code is as follows:
import numpy as np
data = [0x13693, 0x6b2c0, 0x11a9f9, 0x157000, 0x1cb91, 0x1bb528, 0x1bb528, 0xded21, 0x144f38, 0xfb89d, 0x169b48, 0xd151f, 0x8b98b, 0x17d140, 0xded21, 0x1338c0, 0x1338c0, 0x11a9f9, 0x1b000, 0x144f38, 0x1734eb]
s = ""
for d in data:
i = round(np.cbrt(d))
s+=chr(i)
print(s)
When we run the ramada program with this string as the flag kernel we get:
We have found the flag 🥳
FIN.