Skip to main content

Mob psycho picoCTF 2024 Solution

Examine the internals of an Android application package to locate and decode a hidden flag.

Published: April 3, 2024Updated: August 25, 2026

Description

Can you handle APKs? Download the android apk here.

APK unpacking

Download mobpsycho.apk and unzip it in a separate directory (APK unzip dumps lots of files).

bash
wget https://artifacts.picoctf.net/c_titan/53/mobpsycho.apk && \
mkdir mobpsycho_dir && cd mobpsycho_dir && \
unzip ../mobpsycho.apk

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
The Hex Dumps for CTF guide covers the xxd -r -p reverse-hex pattern at the heart of this solve, plus the recognition cues for hex-encoded strings hidden inside other formats.
  1. Step 1Find the flag file
    Observation
    The download is an APK, and Android apps keep raw resources, text and config and assets, under res/ inside the ZIP. Scan that directory with find and strings.
    Search the extracted tree by filename first, then by content. The flag lives at res/color/flag.txt. Note that grepping for the literal string 'flag' inside the files finds nothing here: the flag is stored hex-encoded, so the giveaway is the byte pattern 7069636f, which is 'pico' in hex.
    bash
    find . -type f -name 'flag*'
    bash
    grep -rl 7069636f res
    What didn't work first

    Tried: Run strings on the APK file directly before unzipping it

    Running strings on the .apk floods you with ZIP metadata and DEX fragments, and the flag is buried or missing entirely, because compression means those bytes are not ASCII on disk. Unzip first so strings sees the uncompressed resource files.

    Tried: Grep the extracted tree for the string 'flag' or 'picoCTF' and conclude the flag is not in the APK

    The flag is stored as hex text, so neither 'picoCTF' nor 'flag' appears anywhere in the file contents. Search by filename, or grep for the hex of the prefix (7069636f), and res/color/flag.txt shows up immediately.

    Learn more

    An APK (Android Package Kit) is simply a ZIP archive containing everything an Android app needs: compiled Dalvik bytecode (classes.dex), resources, assets, a manifest, and native libraries. Because it is a standard ZIP, any tool that can unzip an archive can explore its contents without needing a real Android device.

    find . -type f -name 'flag*' is the cheapest first pass: it walks the whole extracted tree by filename and costs nothing. When a name search comes up empty, find ... -exec strings {} + | grep ... applies strings to every regular file and pipes the union into grep, which is the safer alternative to a top-level strings *: that glob skips dotfiles, expands at most one level, and chokes on directories. Scoping either search to res/ avoids dragging classes.dex into the output.

    • The res/ directory holds Android XML resources, drawables, and raw files, a common hiding spot for CTF secrets.
    • The assets/ directory is another frequent location for embedded files that are not compiled into the DEX.
    • For deeper analysis, tools like jadx or apktool decompile DEX bytecode back to readable Java/Smali.
  2. Step 2Decode the hex
    Observation
    flag.txt is an unbroken run of hex character pairs with no offsets or spaces, which is a plain hex dump. xxd -r -p converts it back to ASCII.
    flag.txt contains hex; pipe it through xxd -r -p (or CyberChef's From Hex) to recover the ASCII flag.
    bash
    xxd -r -p res/color/flag.txt

    Expected output

    picoCTF{ax8mC0RU6ve_NX85l4ax8mCl_a3e...}
    What didn't work first

    Tried: Run xxd -r res/color/flag.txt without the -p flag

    Without -p, xxd -r expects its own address-offset layout. flag.txt is a continuous hex string with no offsets, so you get garbled or empty output. -p tells xxd the input is plain hex with no columns.

    Tried: Open flag.txt in a text editor and read it as the flag

    flag.txt reads as a long string of hex digits, which is not a valid flag. Each pair encodes one character, so the flag is what those pairs decode to. The raw string gets rejected.

    Learn more

    Hiding data as hexadecimal is a simple obfuscation technique: each byte of the original string is represented as two hex digits (e.g., the letter 'p' becomes 70). The value is human-unreadable at a glance but trivially reversible.

    xxd -r -p reverses a plain hex dump back to binary. The -r flag means "reverse" (hex to binary) and -p means the input is in plain/continuous hex format without address offsets. This combination is the standard Linux one-liner for hex decoding.

    CyberChef's From Hex recipe performs the same operation visually, making it useful when you want to see intermediate steps or chain multiple decodings (e.g., hex then base64 then ROT13). Real malware samples often layer encodings precisely to slow down analysts.

    The decoded output is pure ASCII printable text from p through }: that's the entire flag, copy it as-is. If you see \0 or other null bytes inside the output, that's a sign the input hex had odd-length bytes, stray spaces, or trailing whitespace that xxd -r -p mishandled, not part of the flag itself.

Interactive tools
  • File Magic IdentifierIdentify file types from magic numbers. Paste hex bytes or drop a file to detect PNG, JPEG, ZIP, PDF, ELF, PCAP, SQLite, and dozens of other formats.
  • Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.

Flag

Reveal flag

picoCTF{ax8mC0RU6ve_NX85l4ax8mCl_a3e...}

The decoded hex string inside res/color/flag.txt is the flag.

Key takeaway

An APK is an ordinary ZIP archive, so anything bundled as a raw resource is readable by anyone with unzip, no device or emulator involved. Developers still tuck API keys and credentials into res/ or assets/ on the assumption that an installed app cannot be inspected, and that assumption is wrong. The same workflow, unzip then strings then grep, with jadx for the DEX, is what real Android assessments and bug bounty work use.

Related reading

Tools used in this challenge

Where to go next