Description
A provided PIN checker binary validates an 8-digit code one character at a time. Because it returns more slowly for each correct digit, you can abuse the timing difference to recover the full PIN and then use it to obtain the flag from the remote service.
Setup
Fetch `pin_checker`, mark it executable, and probe it with sample 8-digit inputs while timing execution.
Notice that each correct digit increases the runtime slightly-classic timing side channel behavior.
Write a script (pwntools + `time.perf_counter`) to brute-force each position, then submit the final PIN to the remote service.
wget https://artifacts.picoctf.net/c/74/pin_checker
chmod +x pin_checker
echo "11111111" | time ./pin_checker
python3 solve_pin.py
nc saturn.picoctf.net 53639
Solution
- Step 1Confirm the timing leakRunning `echo "11111111" | time ./pin_checker` and then tweaking one digit shows the runtime grows whenever the prefix is correct. That leak lets us learn each digit sequentially.
- Step 2Automate the measurementUse pwntools (or direct `subprocess`) to spawn the checker, send a candidate PIN, and measure the elapsed time with `time.perf_counter()`. For each position 0–7, test digits 0–9 and keep whichever produced the longest runtime, then lock it in before moving to the next index.
- Step 3Redeem the PINAfter the script prints the full PIN, connect to `nc saturn.picoctf.net 53639`, enter the recovered code when prompted, and the service responds with the flag.
Flag
picoCTF{t1m1ng_4tt4ck_914c...}
Timing side channels are powerful-even without reading the binary, runtime differences disclosed the entire secret.