Description
Don't just analyze this binary statically - use dynamic analysis to find the flag. The binary validates input at runtime.
Setup
Download the binary and make it executable.
wget https://mercury.picoctf.net/static/.../challchmod +x challSolution
Walk me through it- Step 1Try ltrace - it usually leaks the comparison directlyRun 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 -50bashltrace -e strcmp+memcmp+strncmp ./chall <<< 'picoCTF{test}' 2>&1bashstrace -e openat,read ./chall <<< 'picoCTF{test}' 2>&1 | head -50Learn 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. - Step 2Use GDB to intercept the comparisonIf 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 ./challbash# (gdb) catch syscall readbash# (gdb) break memcmpbash# (gdb) run 'picoCTF{test}'bash# At breakpoint: x/s $rdi, x/s $rsiLearn more
Breakpoints on common comparison functions: Even in statically linked binaries,
memcmpand 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.