Description
A classic Crackme. Find the password, get the flag! Binary can be downloaded here. Crack the Binary file locally and recover the password. Use the same password on the server to get the flag! Access the server using nc titan.picoctf.net 56916
Setup
Download crackme100 and analyze it with Ghidra/objdump to understand the password mangling loops.
Use gdb to break just before setvbuf and read the comparison string from memory (info locals).
wget https://artifacts.picoctf.net/c_titan/83/crackme100 && \
chmod +x crackme100 && \
objdump -D crackme100 | lessSolution
- Step 1Capture the mangled targetIn gdb, break at 0x4011e8 (right before setvbuf). After entering any password, run info locals to see the local_* buffers. Copy the target string stored in local_68.
gdb crackme100 # break *0x4011e8; run; info localsLearn more
A crackme is a program specifically designed to be reverse-engineered - the goal is to find the correct password or license key without access to the source code. Crackmes are a foundational exercise in binary reversing and are used extensively in CTF competitions and professional malware analysis training.
GDB (GNU Debugger) is the standard debugger for Linux binaries. Setting a breakpoint (
break *0x4011e8) at a specific address halts execution there, letting you inspect registers, stack frames, and local variables. Theinfo localscommand dumps all local variables in the current stack frame, which often reveals the expected password value if the binary stores it in cleartext for comparison.The
setvbuffunction is a C library call that configures I/O buffering. Crackmes often call it early to ensure output appears immediately. Breaking just before it lets you catch the program in an initialized but not-yet-interactive state - a good point to examine what the binary has set up in memory.In professional reverse engineering, this dynamic analysis approach (running with a debugger) complements static analysis (reading disassembly). Dynamic analysis shows actual runtime values that static analysis may not resolve, especially when values come from computed addresses or obfuscated initialization routines.
- Step 2Reverse the loopWrite a short Python helper that subtracts the same per-character offsets applied in main(). Running it three times in reverse order reconstructs the true password.
python3 solver.py # reverse the modulo-26 mathLearn more
The password mangling loop applies a modulo-26 Caesar-style shift to each character. This is a simple but instructive obfuscation: instead of comparing
input == "secret", the binary comparesmangle(input) == mangled_target. An attacker who only sees the comparison value must reverse the mangling to recover the original password.Modular arithmetic underlies much of classical cryptography. For a shift of +N mod 26, the inverse is -N mod 26 (or equivalently, +(26-N) mod 26). Python handles this cleanly with the
%operator, which always returns a non-negative result for positive modulus - unlike C, where the result can be negative for negative operands.The "run it three times in reverse order" instruction refers to the structure of the mangling loop: if encryption applies operations A then B then C, decryption must apply C-inverse then B-inverse then A-inverse. This is the same principle used in block cipher decryption and in reversing any composed function.
Writing a dedicated solver script, rather than doing the math by hand, is best practice even in CTFs. A script is reproducible, debuggable, and reusable - and for crackmes with larger character sets or more complex transforms, manual reversal quickly becomes impractical.
- Step 3Submit remotelyTest the recovered password against the local binary, then connect to nc titan.picoctf.net 56916 and enter it to receive the real flag.
nc titan.picoctf.net 56916Learn more
Testing locally before submitting remotely is a critical habit in CTF and real-world exploitation. Local testing eliminates network latency, lets you iterate quickly, and ensures your solution works before you consume your limited attempts against a rate-limited or single-attempt remote service.
netcat (
nc) provides a raw TCP connection to the server - no HTTP, no TLS, no protocol framing. You type directly to the server process's stdin and see its stdout in your terminal. This makes it ideal for interacting with custom CTF services that implement their own simple text protocols.The pattern of cracking locally and then submitting the answer remotely is common in binary exploitation challenges. The remote service often runs the same binary but returns the actual flag only after correct authentication, preventing flag exposure in the downloadable binary itself.
From a security perspective, this challenge illustrates why storing passwords as mangled (but reversible) strings in a binary provides very weak protection. Any determined attacker with access to the binary can recover the password through static or dynamic analysis. Real applications should use proper password hashing (bcrypt, Argon2, scrypt) that is computationally hard to reverse.
Related guides
How to Use Ghidra for Reverse Engineering CTF Challenges
A full walkthrough of Ghidra: importing binaries, reading decompiled C, finding strings, and tracing password comparison logic.
Beginner's Guide to Netcat for CTFs
This challenge ends with nc submission. Learn how nc works and how to automate it for challenges with more complex interactions.
Flag
picoCTF{s0lv3_angry_symb0ls_150f...}
Entering the recovered password on the remote instance prints the flag.