Skip to main content

droids0 picoCTF 2019 Solution

Explore and decompile an Android APK to locate a flag hidden somewhere in the application.

Published: April 2, 2026Updated: August 25, 2026

Description

Where do droids log things? Run droids0.apk in an emulator, press the button, and check the Android system log for the flag.

Download the APK file.

Install Android Studio and configure an Android Virtual Device (AVD) emulator.

bash
wget <url>/droids0.apk

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Install and run the APK in an Android emulator
    Observation
    The description says to check the Android system log. So the flag never appears on screen; it goes out through a log call you can read with adb logcat.
    Install the APK using ADB, launch it in the emulator, and press the Flag button. The flag is written to the Android system log (logcat) rather than displayed on screen. Watch logcat while pressing the button.
    bash
    adb install droids0.apk
    bash
    # Launch the emulator and open the app, then:
    bash
    adb logcat | grep picoCTF

    Expected output

    D/PICO_FLAG( 1234): picoCTF{a.moose.once.bit.my.sister}
    What didn't work first

    Tried: Run 'strings droids0.apk | grep picoCTF' to extract the flag without an emulator

    strings on the APK finds nothing useful, because the flag is built and emitted at runtime through Log.d() rather than stored as a literal. It only exists as logcat output after the button is pressed, so static extraction comes up empty.

    Tried: Use 'adb logcat -s PICO_FLAG' expecting to filter by tag name

    The -s flag filters by tag, which works only if you already know the exact tag. Grepping the raw stream for picoCTF is safer when you do not: guess the wrong tag and you get silence, which looks identical to the flag never being logged.

    Learn more

    Android's logcat is the system logging output. Apps write to it using Log.d(tag, message), Log.i(), Log.e(), etc. Log messages are invisible to normal users but fully visible over ADB to developers (and attackers). In this challenge, instead of displaying the flag on screen, the app writes it to the log.

    adb logcat | grep picoCTF filters the continuous log stream for lines containing the flag prefix. Alternatively, Android Studio's Logcat window provides a GUI filter. You can also use adb logcat -s PICO_FLAG to show only log entries with the 'PICO_FLAG' tag.

  2. Step 2Read the flag from logcat
    Observation
    Pressing the button produces a logcat line tagged PICO_FLAG. The flag is assembled at runtime, so it just needs copying out of that output.
    The flag appears in the logcat stream when the button is pressed. Copy the full picoCTF{...} string from the output.
    Learn more

    This challenge demonstrates a common Android security mistake: logging sensitive data. In production apps, log statements should be removed or disabled in release builds because logcat is accessible to any process with the READ_LOGS permission and to anyone with adb access.

    To verify this statically: jadx droids0.apk -d droids0_java/ then look at MainActivity to see the Log.d() call that outputs the flag to logcat.

Interactive tools
  • 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.
  • 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.
  • Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.

Flag

Reveal flag

picoCTF{a.moose.once.bit.my.sister}

The flag is logged to Android logcat when the button is pressed - run in an emulator and watch adb logcat output.

Key takeaway

Android logcat is a broadcast channel, not a private one. Any app with READ_LOGS, any connected ADB session, and any developer tool can read every message every app writes. Logging credentials, tokens, or other secrets is CWE-532 and turns up constantly in mobile penetration test reports. ProGuard and R8 can strip log calls from release builds, but the safer habit is never logging sensitive data at all.

Related reading

Useful tools for Reverse Engineering

Where to go next