Description
A PIE-protected binary leaks the address of `main` each time you connect. Use that leak to compute the absolute address of `win` and jump there instead of returning to `main`.
Setup
Fetch both the binary and its source so you can inspect the control flow (`win` simply prints the flag).
Connect to `nc rescued-float.picoctf.net 59193` and note the leaked address of `main`.
Use objdump or radare2 locally to record the offsets of `main` and `win` inside the binary.
wget https://challenge-files.picoctf.net/c_rescued_float/2736a730340dbe9969fe3104da0cca0c60eddaf1fedb0e220b5df5a3f3cf015f/vuln.c
wget https://challenge-files.picoctf.net/c_rescued_float/2736a730340dbe9969fe3104da0cca0c60eddaf1fedb0e220b5df5a3f3cf015f/vuln
objdump -D vuln | grep -E "<win>|<main>"
Solution
- Step 1Derive the PIE baseWrite down the leaked `main` address from the remote service. Subtract the local `main` offset (0x133d) to recover the PIE base address for that run.pie_base = leaked_main - 0x133d
- Step 2Compute the win addressAdd the known `win` offset (0x12a7) to the PIE base to get the absolute address of `win`. A three-line Python helper that does `win_address = leaked_main - main_offset + win_offset` keeps the math simple.win_address = leaked_main - 0x133d + 0x12a7
- Step 3Send the target addressReconnect (or keep the connection open), paste the computed `0x...` value when prompted, and the binary jumps straight into `win`, printing the flag.
Flag
picoCTF{b4s1c_p051t10n_1nd3p3nd3nc3_31cc...}
Keep one terminal open with nc to grab the current leak and a second to run the helper script so the values stay in sync.