Using Ghidra decompiler, we managed to get back the code source of the program.
After reading the code source, it seems that it is generating a random password.
Looking at the line 42, printf(username) is a Format String Vulnerability. The parameter passed to the function printf() is not a format parameter such as %d, %s, %f etc. In this case, if username = %d then it will print an unknown integer value.
Let's do some test.
Instead of using %d, let's use %x to leak addresses stored in the memory.
Some addresses have been leaked, let'a analyze this in GDB to have a clearer view. The goal in this challenge is to use the format string vulnerability to leak the password that is generated randomly.
Visualizing in GDB
Putting a breakpoint at the address 0x40184f,
cmp dword ptr [rbp - 0x128], 0, the password that has been generated randomly through the loop is stored in the register RAX.
4 addresses have been printed by using "%x %x %x %x" as input in the program. We notice that
4c2880 is an address of the stack, this value is stored in the register R9. Therefore, we managed to leak some address of the stack. Awesome, let's see if we can leak the passwod that has been generated randomly.
First we need to locate where the password is stored in the stack.
The password is loated at the address 0x7fffffffffffe080, his length is 20 characters. If we look back at the source code,
cpt = 20. It starts at the address 0x7fffffffffffe080 to 0x7fffffffffffe094.
Let's add more %x this time.
Cool we see the value 39703649 and this is the value at the address 0x7fffffffffffe080 but the next one is 757a5058, some values are missing there...
This is because %x has a maximum value of 4294967295 which correspond to 0xFFFFFFFF in hexadecimal so it cannot print more bytes that 0xFFFFFFFF. To print large value we need to use %lx instead of %x.
r < <(python -c "import sys; sys.stdout.buffer.write(b'ABCD' + b'%lx '* 30)")
The password has been leaked. Looks like we simply need 18 %lx to print the password.
bytes.fromhex("654130796f2e5331356c34536d5043722f4d3452").decode("ascii")
'eA0yo.S15l4SmPCr/M4R'
If you notice, we need to be careful about the bytes order. We might need to convert the bytes in big endian when doing our script.
Scripting