old bridge

The file have almost all protections but the reallocation read only enabed.

Pasted image 20250107214707.png

We can put this binary in IDA to the a disassemble.

Pasted image 20250107201038.png

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().

Pasted image 20250107201434.png

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".

Pasted image 20250107221711.png

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.

Pasted image 20250107223143.png

Let's attach a debugger and use the pwndbg's canary command to verify the value.

Pasted image 20250107223316.png

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 stack pivoting in order to store our chain in the start of the payload.

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.

Pasted image 20250107225251.png

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.

Pasted image 20250107230557.png

And when checking it against the base address got from pwndbg's libs command.

Pasted image 20250107230451.png

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!

Screenshot_20250107_231813.png

Last updated