This time HackIM had a variety of RE challenges. There was one LLVM IR, one ARM, one Mach-O, one Linux x64 and one more(didn't unlock it, so don't know about that).
I solved the ARM challenge, named Quad math. It was a 150 pointer challenge. I couldn't run it. So I fired up radare to analyse it statically. The main function looked something like this:
From the disassembly, it is clear that the binary takes one string as input, then it goes through a series of checks, and finally the result gets printed out. There were a total of 65 check functions which checked the input, character by character. But the checks turned out to be a little short as multiple correct answers were being accepted by the binary. It will become clear in a little while. And each of the checking functions looked something like this:
It is actually checking the first and third character of the input(i.e. flag).
void func_6b8()
{
fin = input[0] * input[0] - 203 * input[0] != -10296 || input[2] * input[2] - 203 * input[2] != -10296;
}
Rest of the characters were being checked similarly(i.e. two alternate characters at a time). So, what I did is, I wrote a z3 script to find the correct input.
As I earlier said, the constraints for checking the flag were a little less, therefore the script printed out many possible answers. So I sent few of them having only printable characters to the admin and he was kind enough to send me the correct flag which will be accepted by the server.
The correct flag was:
hackim18{'W0W_wow_w0w_WoW_y0u_h4v3_m4th_sk1ll5_W0oW_w0ow_wo0w_Wo0W'}
I solved the ARM challenge, named Quad math. It was a 150 pointer challenge. I couldn't run it. So I fired up radare to analyse it statically. The main function looked something like this:
From the disassembly, it is clear that the binary takes one string as input, then it goes through a series of checks, and finally the result gets printed out. There were a total of 65 check functions which checked the input, character by character. But the checks turned out to be a little short as multiple correct answers were being accepted by the binary. It will become clear in a little while. And each of the checking functions looked something like this:
It is actually checking the first and third character of the input(i.e. flag).
void func_6b8()
{
fin = input[0] * input[0] - 203 * input[0] != -10296 || input[2] * input[2] - 203 * input[2] != -10296;
}
Rest of the characters were being checked similarly(i.e. two alternate characters at a time). So, what I did is, I wrote a z3 script to find the correct input.
As I earlier said, the constraints for checking the flag were a little less, therefore the script printed out many possible answers. So I sent few of them having only printable characters to the admin and he was kind enough to send me the correct flag which will be accepted by the server.
The correct flag was:
hackim18{'W0W_wow_w0w_WoW_y0u_h4v3_m4th_sk1ll5_W0oW_w0ow_wo0w_Wo0W'}