UP | HOME

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

Author: rick

Email: rick@gnous.eu

Created: 2024-05-16 jeu. 20:32

Validate