Let's get dynamic picoCTF 2021 Solution

Published: April 2, 2026

Description

Don't just analyze this binary statically - use dynamic analysis to find the flag. The binary validates input at runtime.

Download the binary and make it executable.

bash
wget https://mercury.picoctf.net/static/.../chall
bash
chmod +x chall
Companion reading: GDB for CTF walks through the breakpoint-on-strcmp idiom used here when ltrace alone isn't enough.
  1. Step 1Try ltrace - it usually leaks the comparison directly
    Run the binary under ltrace with dummy input. A line shaped like strcmp("your_input", "the_flag") = 1 reveals the expected value without any reverse engineering. Fall back to strace if the check is implemented as a syscall or read-from-file.
    bash
    ltrace ./chall <<< 'picoCTF{test}' 2>&1 | head -50
    bash
    ltrace -e strcmp+memcmp+strncmp ./chall <<< 'picoCTF{test}' 2>&1
    bash
    strace -e openat,read ./chall <<< 'picoCTF{test}' 2>&1 | head -50
    Learn more

    Dynamic analysis tools observe a program's behavior while it is running, rather than reading the binary statically. This is powerful because it bypasses obfuscation: no matter how complex the code, the final comparison must actually happen at runtime, and tracing tools can intercept it.

    strace captures system calls - interactions between the program and the kernel. Useful for finding file reads (openat, read), network activity (connect, send), and process control (fork, execve).

    ltrace captures calls to shared library functions (libc, libssl, etc.). Useful for finding strcmp, memcmp, crypto functions, and other library-level comparisons that reveal expected values.

  2. Step 2Use GDB to intercept the comparison
    If ltrace does not reveal the comparison (e.g., the binary is statically linked), load it in GDB and set breakpoints on comparison instructions. Inspect registers when the breakpoint fires.
    bash
    gdb -q ./chall
    bash
    # (gdb) catch syscall read
    bash
    # (gdb) break memcmp
    bash
    # (gdb) run 'picoCTF{test}'
    bash
    # At breakpoint: x/s $rdi, x/s $rsi
    Learn more

    Breakpoints on common comparison functions: Even in statically linked binaries, memcmp and similar functions from the C library are still present in the binary (not as dynamic imports, but as compiled-in functions). You can break on them by address after finding them in the symbol table (nm chall | grep memcmp) or by setting breakpoints on the disassembled addresses where the comparison occurs.

    GDB scripting: For comparisons done in a loop (character by character), use a GDB Python script or commands script to automate: break on the comparison instruction, print the expected byte, continue, and repeat until the full flag is assembled.

Flag

picoCTF{...}

Dynamic analysis (ltrace/strace/GDB) intercepts the comparison at runtime regardless of static obfuscation - the correct value must be present in memory at the moment of comparison.

Want more picoCTF 2021 writeups?

Useful tools for Reverse Engineering

Related reading

What to try next