Description
Reverse this linux executable?
Setup
Download the out binary from the challenge artifacts.
Have upx, strings, and optionally strip/Ghidra handy.
wget https://artifacts.picoctf.net/c_titan/22/out && \
strings out | head && \
upx -d out && strip outSolution
- Step 1Spot the packerstrings out reveals UPX markers. Run upx -d out to unpack, then strip out to remove excess symbols (as hinted).
upx -d out && strip outLearn more
UPX(Ultimate Packer for eXecutables) is an open-source executable packer that compresses a binary's code and data, prepends a small decompression stub, and produces a self-contained file that is typically 50–70% smaller than the original. At runtime, the stub decompresses the original binary into memory and jumps to it, so the packed file executes identically to the original.
Malware authors frequently use UPX (or custom packers inspired by it) to shrink payloads and hinder static analysis - a packed binary's code section looks like compressed data to most disassemblers. The telltale signs of UPX packing visible via
stringsare theUPX!magic bytes and the section namesUPX0andUPX1.upx -d out- decompresses in-place; the file is overwritten with the original ELF.strip out- removes symbol table and debug info, further reducing size (the challenge hints at this step).- If the binary used a custom or modified packer, you would need to dump the process memory at runtime instead.
- Step 2Load into GhidraAnalyze the unpacked binary. In entry(), numerous prompts appear; one contains a long hex string. That value is the flag in hex form.
Learn more
Ghidrais NSA's free, open-source reverse engineering suite. It disassembles machine code into assembly and then decompiles it into readable C-like pseudocode, making it far easier to understand program logic than reading raw bytes. It supports virtually every common CPU architecture and binary format.
The entry() function is the real start of execution in a C program - it calls library initializers and then invokes
main(). In CTF binaries the flag is often embedded as a string literal inmainor a function it calls, where it shows up in Ghidra's decompiled output as a long quoted constant.When you see a long hex literal in decompiled code it is almost always encoded data: a flag, a key, or an obfuscated string. The pattern here - a hex blob inside an executable - is one of the most common beginner reverse-engineering CTF techniques.
- Step 3Convert from hexPaste the hex below into CyberChef (From Hex) or run the echo command to decode it locally; the resulting ASCII string is the flag.
7069636f4354467b5539585f556e5034636b314e365f42316e34526933535f35646565343434317decho 7069636f4354467b5539585f556e5034636b314e365f42316e34526933535f35646565343434317d | xxd -r -pLearn more
Converting from hex to ASCII is one of the most fundamental operations in CTF challenges. Each pair of hex digits maps directly to one ASCII character:
70is 'p',69is 'i',63is 'c', and so on. Recognizing that a string starts with7069636f(= "pico") is a huge hint that you've found the flag encoding.xxd -r -pis the standard reverse-hex tool on Linux. The-rflag reverses the operation (hex to binary) and-pindicates plain/continuous hex input without address columns. For flag strings that are pure ASCII, the binary output is readable directly.CyberChef is an excellent alternative for interactive exploration - it also supports chained decodings, so if you encounter hex-within-base64 or similar layering, you can stack recipes to unpack everything in one view.
Flag
picoCTF{U9X_UnP4ck1N6_B1n4Ri3S_5de...}
Decoding the embedded hex string reveals the flag above.