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_checkerchmod +x pin_checkerecho "11111111" | time ./pin_checkerpython3 solve_pin.pync saturn.picoctf.net 53639Solution
- 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.
Learn more
A timing side-channel attack exploits the fact that a program takes measurably different amounts of time depending on secret data. In this case, the PIN checker validates digits left-to-right and exits early on the first mismatch - so a PIN with 3 correct leading digits takes longer than one with 0 correct digits.
This is the same class of vulnerability that affects naive string comparison in authentication code. Languages like Python return from
==as soon as a character mismatches, which leaks information about how far into the string the comparison succeeded. Secure implementations use constant-time comparison - they always check every byte regardless of where a mismatch occurs, so timing reveals nothing.In Python,
hmac.compare_digest(a, b)provides constant-time string comparison. In C,memcmpis not constant-time; security libraries provide safe alternatives likeCRYPTO_memcmp(OpenSSL) ortimingsafe_bcmp(BSD libc). - 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.
Learn more
pwntools is a Python library designed for CTF challenges and exploit development. Its
process()andremote()classes make it easy to spawn local processes or connect to remote services, send inputs, and read responses. Combined withtime.perf_counter()for high-resolution timing, it's the standard toolkit for timing attacks.The brute-force strategy here works digit by digit: fix the known-correct prefix, try all 10 digits for the next position, and pick the one that takes longest. This reduces the search space from 10^8 (100 million) combinations to just 10 × 8 = 80 measurements - a massive speedup that makes the attack practical in seconds.
Real-world timing attacks require careful statistics to handle noise. Network latency introduces variance, so attackers typically repeat each measurement hundreds of times and take the median or minimum. Tools like tlsfuzzer implement statistical timing analysis for remote attacks against TLS implementations, where differences as small as nanoseconds can be detected over a network.
- 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.
Learn more
netcat (
nc) is a versatile networking tool that opens raw TCP or UDP connections. It's described as the "TCP/IP Swiss Army knife" - you can use it to connect to any open port and send/receive arbitrary data. For CTF challenges, it's the standard way to interact with remote challenge servers that expose a text-based interface.Timing side channels have been exploited against major real-world systems: early TLS implementations leaked RSA key bits through timing differences during decryption (Bleichenbacher's attack), and CPU branch prediction has been abused in the Spectre and Meltdown vulnerabilities to leak memory across security boundaries using cache timing.
The defense against this class of attack is comprehensive: constant-time algorithms, adding random delays (jitter), and rate-limiting repeated authentication attempts. Modern security standards like FIPS 140-3 require constant-time implementations for cryptographic operations precisely because timing leaks can undermine otherwise mathematically sound algorithms.
Flag
picoCTF{t1m1ng_4tt4ck_914c...}
Timing side channels are powerful-even without reading the binary, runtime differences disclosed the entire secret.