Post

You Cant C Me


The challenge binary is a 64-bit ELF file format as can be seen below. Also this file is stripped so the debugging symbols will not be present in this file. This will make the analysis a bit harder.

1
2
$ file auth 
auth: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, stripped

On executing the challenge binary, it prints ‘Welcome’ and asks for some input. Here, ‘ape’ was entered but failed obviously. We need to reverse it to retrieve the correct key.

1
2
3
4
$ ./auth 
Welcome!
ape
I said, you can't c me!

First thing I usually like to do is load the binary in Ghidra. Since this binary is stripped, it might be harder to locate main. The main function is located at FUN_00401160.

Ghidra

  • It can be seen that the userInput is compared to a generatedKey value with strcmp, which will be generated at run-time.
  • If the userInput matches, it seems to print the flag. Otherwise, it prints ‘I said, you can’t c me!’.

Lets use GDB to retrieve the generatedKey value.

1
$ gdb -q auth

Before doing anything, lets set the syntax to Intel because I am comfortable with it. The default one is AT&T.

1
(gdb) set disassembly-flavor intel

Since the binary is stripped the debugging symbols will not be present. Lets check the non-debugging symbols.

1
2
3
4
5
6
7
8
(gdb) info functions
All defined functions:

Non-debugging symbols:
0x0000000000401030  printf@plt
0x0000000000401040  fgets@plt
0x0000000000401050  strcmp@plt
0x0000000000401060  malloc@plt

We know from Ghidra that the user input value will be compared with generatedKey value with strcmp. On above output, the call to strcmp is at 0x0000000000401050. So lets add breakpoint on that address and run the program. Again, ‘ape’ was entered as user input.

1
2
3
4
5
6
7
8
9
(gdb) b *0x0000000000401050
Breakpoint 1 at 0x401050

(gdb) r
Starting program: /home/remnux/HTB/RE/auth 
Welcome!
ape

Breakpoint 1, 0x0000000000401050 in strcmp@plt ()

The program has hit breakpoint at strcmp. Lets now check the memory value of RDI and RSI registry to get the generatedKey.

1
2
3
4
5
gdb) x/s $rsi
0x4056b0:	"ape\\n"

(gdb) x/s $rdi
0x7fffffffdfb0:	"wh00ps!_y0u_d1d_c_m3"

We have the generatedKey and we can get the flag.

1
2
3
4
$ ./auth 
Welcome!
wh00ps!_y0u_d1d_c_m3
HTB{wh00ps!_y0u_d1d_c_m3}


Alternatively, using ltrace.

1
2
3
4
5
6
7
8
9
10
11
ltrace ./auth

printf("Welcome!\\n"Welcome!
)                                                                                                              = 9
malloc(21)                                                                                                                        = 0x83b6b0
fgets(ape
"ape\\n", 21, 0x7f57637e6980)                                                                                                = 0x83b6b0
strcmp("wh00ps!_y0u_d1d_c_m3", "ape\\n")                                                                                           = 22
printf("I said, you can't c me!\\n"I said, you can't c me!
)                                                                                               = 24
+++ exited (status 0) +++

This post is licensed under CC BY 4.0 by the author.

Trending Tags