Need For Speed picoCTF 2019 Solution

Published: April 2, 2026

Description

The binary decodes the flag but it takes too long. Speed it up to get the flag.

Download the binary and make it executable.

bash
wget <url>/need-for-speed
bash
chmod +x need-for-speed
  1. Step 1Run the binary and observe the delay
    Execute the binary. It will print something like 'Calculating key...' and then hang for a very long time (or use alarm() to kill itself after a few seconds). The actual flag decoding logic is correct - only the artificial delay prevents you from seeing the output.
    bash
    ./need-for-speed
    Learn more

    Binaries can use sleep(), alarm(), or busy-wait loops to introduce artificial delays. alarm(n) sends SIGALRM to the process after n seconds, killing it by default. These are used in CTF challenges as anti-automation measures.

  2. Step 2Use GDB to set the key variable and call print_flag directly
    Open the binary in GDB. Break at main and run. Use GDB's disassemble to find the address of the key global variable (GDB often annotates it directly). Set the key to the value calculate_key() would have returned (0x06b3b3 per Martin's analysis), then call print_flag() directly.
    bash
    gdb ./need-for-speed
    bash
    break main
    bash
    run
    bash
    # Find the key address - GDB labels it in the disassembly:
    bash
    disassemble get_key
    bash
    # Set the key to the hardcoded return value from calculate_key:
    bash
    set *<key_address> = 0x6b3b3
    bash
    # Or call print_flag directly:
    bash
    call (void)print_flag()
    bash
    continue
    Learn more

    GDB can read and write arbitrary memory locations and call functions directly. disassemble function_name shows the assembly with comments annotating global variable addresses. set *0xADDRESS = value writes to a memory location. call (void)function() invokes a function from within GDB.

    Martin found the key value by reading the calculate_key() source (it returns 0x06b3b3 after the artificial delay loop). Setting the global key variable to that value and then calling print_flag() skips the timing entirely.

  3. Step 3Read the flag
    After bypassing the delay, the binary completes its flag decoding and prints it. Copy the output.
    Learn more

    Patching a binary with xxd + a hex editor is another approach: find the call alarm instruction bytes and overwrite them with NOP instructions (0x90). This permanently removes the delay from the binary file.

Flag

picoCTF{...}

Use GDB to intercept and neutralize the alarm() call, then let the binary run to completion and print the flag.

Want more picoCTF 2019 writeups?

Useful tools for Reverse Engineering

Related reading

What to try next