Last updated
Last updated
The file have almost all protections but the reallocation read only enabed.
We can put this binary in IDA to the a disassemble.
This part of the program consists in setting up a listener on the port provided in the argv[1]
. When a connection is received, the program calls fork()
before sending the file descriptor of the connection to check_username()
.
We can clearly see a buffer overflow on the line 12, where the function read
reads 1056 bytes from the file descriptor and writes it into the buf[1032]
array. After it, the program does a XOR operation to the entire received array with the 0x0D
byte and compare the start of the xored array with the string "davide".
Back on the main function, the program checks the result of check_username()
and, if it went with success, the it prints the string "Username found", if not, it just exits.
To explore this in order to control the execution flow, we must get a way to leak the canary value. As mentioned before, the binary calls fork()
before calling check_username()
, so we can use brute it byte per byte using the same technique used on the rope machine taking advantage that we can differentiate when the program crashes by receiving or not the username found string.
Executing it and reading the canary value, we got a QWORD that seems like a canary.
Let's attach a debugger and use the pwndbg's canary
command to verify the value.
To explore this, we would need to use a leave
instruction to change the value stored in RBP to RSP, effectively controlling the stack start.
As detailed in my rope writeup, we would need to brute RBP in order to get the return address, so we can use our brute_8_bytes
function.
After run the current version of the exploit, we can get the return address.
Now, we can calculate the libc address value by simply subtracting the offset from the value.
Doing the operation in the debugger, we get this value.
And when checking it against the base address got from pwndbg's libs
command.
The challenge has a syscall
gadget, so we can use it to summon how much syscalls we desire, including dup2
, to copy the connection file descriptor to the shell stdin and stdout, and the execve
, to spawn our shell.
Executing the exploit and after a few tries, we got execution xD!
As we only have 24 bytes after the crash, we cannot store a ROP chain in the end of the payload, so we need to use a technique called in order to store our chain in the start of the payload.