packer

Published: April 3, 2024

Description

Reverse this linux executable?

Local reversing

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 out

Solution

  1. Step 1Spot the packer
    strings out reveals UPX markers. Run upx -d out to unpack, then strip out to remove excess symbols (as hinted).
    upx -d out && strip out
    Learn 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 strings are the UPX! magic bytes and the section names UPX0 and UPX1.

    • 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.
  2. Step 2Load into Ghidra
    Analyze 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 in mainor 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.

  3. Step 3Convert from hex
    Paste the hex below into CyberChef (From Hex) or run the echo command to decode it locally; the resulting ASCII string is the flag.
    7069636f4354467b5539585f556e5034636b314e365f42316e34526933535f35646565343434317d
    echo 7069636f4354467b5539585f556e5034636b314e365f42316e34526933535f35646565343434317d | xxd -r -p
    Learn 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: 70 is 'p', 69 is 'i', 63 is 'c', and so on. Recognizing that a string starts with 7069636f(= "pico") is a huge hint that you've found the flag encoding.

    xxd -r -p is the standard reverse-hex tool on Linux. The -r flag reverses the operation (hex to binary) and -p indicates 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.

Want more picoCTF 2024 writeups?

Useful tools for Reverse Engineering

Related reading

What to try next