EZwan
crackmes.one (DirkD)
As the program has been compiled from C, Ghidra doesn't have any
problem to decompile it. As it was not striped, I find the main
in
the functions list. I read quickly the function and see 2 stranges
variables.
local_1a = 0x31201130363c1b55; local_12 = 0x1730;
By reading the ASM code, I understand that it just puts a long digit in the stack.
MOV RAX,0x31201130363c1b55 MOV qword ptr [RBP + local_1a],RAX MOV word ptr [RBP + local_12],0x1730
I think it's our password… Let's check the loop just below. I renamed some variables to be more clear.
printf("Checking Password: %s\n",*(undefined8 *)(argv + 8)); for (i = 0; i < 8; i = i + 1) { if ((*(byte *)((long)&local_1a + (long)(i + 1)) ^ 0x55) != *(byte *)((long)i + *(long *)(argv + 8))) { puts("Wrong Password , please try again! "); exit(0); } } puts("Success , congratulations.");
Welp, I see the password that I must put is the second argument of the
program (as we are in 64 bits, pointers have a size of 8 bits). I can
also find this information just by executing the binary. The password
size is 8, and it compares it to the local_1a
variable, which
contains the strange digit. Let's see it in action in GDB (even if
you're already understood what's going on here).
With GDB, I put a breakpoint on *main
, check the disassembled code
and put more breakpoints on strategic addresses, like the XOR. I do
step by step with ni
, as the program hasn't been compiled with -g
argument. With info registers
, I see the RAX taking the value of
i
, then i + 1
, then 0x1b
. It's a part of our strange digit. With
that, I'm sure that the program is little endian. Here the state of
our memory. If it seems strange, think that is in the stack ! Which is
going from high to low numbers (0x1a
is before 0x12
inside the
stack and check this page from begin.re) :
local_1a local_12 | | v v +------+------+------+------+------+-----+ | 0x55 | 0x1b | 0x3c | .... | 0x30 | 0x17| +------+------+------+------+------+-----+
Ok, with GDB, I've confirmed that the program reads the digit, makes
an XOR on it then compare it with my password. Let's take all the
digits, from local_1a + 1
to the 8th index (which is inside
local_12
), I make an XOR on them and tada, the password appears.
python -c 'print(chr(0x1b ^ 0x55) + chr(0x3c ^ 0x55) + chr(0x36 ^ 0x55) + chr(0x30 ^ 0x55) + chr(0x11 ^ 0x55) + chr(0x20 ^ 0x55) + chr(0x31 ^ 0x55) + chr(0x30 ^ 0x55))'
NiceDude