droids1 picoCTF 2019 Solution

Published: April 2, 2026

Description

Find the password in droids1.apk. The password check compares input against a string resource - decompile the APK with jadx to find the password, then enter it in the emulator to get the flag.

Download the APK file.

bash
wget <url>/droids1.apk

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Decompile with jadx and find the password check
    Observation
    I noticed the challenge is an Android APK with a password check, which suggested decompiling it with jadx to recover readable Java source where the comparison logic and any referenced string resource IDs would be immediately visible.
    Decompile droids1.apk with jadx. Open MainActivity and find the getFlag method. It compares the user input against a string fetched from resources via getString(R.string.password). Look in the strings.xml resource file to read the actual password value.
    bash
    jadx droids1.apk -d droids1_java/
    bash
    cat droids1_java/resources/res/values/strings.xml | grep password
    What didn't work first

    Tried: Use apktool to decompile the APK and look for the password in the smali output.

    apktool produces smali assembly (Dalvik opcodes with register references like v0, p1) rather than readable Java. The string resource reference appears as a hex constant like 0x7f0a0012, which you then have to trace through the resource table manually. jadx decompiles directly to Java and resolves resource names, making the getString(R.string.password) call and the strings.xml lookup trivially readable.

    Tried: Run 'strings droids1.apk' to extract the password directly from the APK binary.

    strings on the raw APK emits a flood of class names, XML tag names, and DEX metadata interspersed with a few readable tokens. String resources live in a compiled binary XML format (resources.arsc) inside the APK, so the password value is not present as a plain ASCII string in the archive. jadx (or aapt dump resources) parses resources.arsc and presents the key-value pairs in a human-readable form.

    Learn more

    Android app logic lives in Java/Kotlin classes compiled to DEX bytecode. The main entry point is typically MainActivity.java. Button click handlers call validation methods. In jadx, search for methods containing string comparisons (equals(), compareTo()) to find password checks.

  2. Step 2
    Find the password construction
    Observation
    I noticed the getFlag method in jadx references getString(R.string.password) rather than a literal, which suggested looking in strings.xml to resolve the resource ID to the actual plaintext password value.
    Read the decompiled check method. The password may be: a string literal, built by concatenating string constants, derived from a formula, or loaded from a resource. Extract the exact string.
    Learn more

    Common obfuscation patterns in Android: StringBuilder used to concatenate parts of the password, Base64 decoding of an encoded string at runtime, or character arrays that are harder for decompilers to identify as strings. The jadx decompiler handles most of these transparently.

  3. Step 3
    Enter the password in the emulator to get the flag
    Observation
    I noticed the app only reveals the flag at runtime after a correct password is entered, which meant I needed to install the APK in an emulator via ADB and submit the password recovered from strings.xml to trigger the flag display.
    Install the APK in an Android emulator using ADB. Launch the app, type the password you found in strings.xml into the text field, and press the button. The app displays the flag when the correct password is entered.
    bash
    adb install droids1.apk
    bash
    # Launch the emulator, open the app, type the password from strings.xml, and press the button
    What didn't work first

    Tried: Patch the APK with apktool to bypass the password check, then reinstall it to get the flag without knowing the password.

    Patching smali requires editing the comparison opcode, re-signing the APK with a debug key, and reinstalling - several error-prone steps. For droids1 the password is stored in plaintext in strings.xml, so reading it directly with jadx is far faster. Patching makes sense only when the password is derived from a runtime computation that cannot be easily read statically.

    Tried: Use 'adb shell input text PASSWORD' to type the password programmatically instead of typing it in the emulator UI.

    adb shell input text works for simple ASCII strings, but if the emulator's soft keyboard is not focused on the input field the command sends keystrokes to whichever element has focus and the field stays empty. The more reliable path is to click the field with adb shell input tap, verify focus, then send input text, or just type directly in the emulator window.

    Learn more

    ADB (Android Debug Bridge) allows you to install, run, and interact with apps on connected devices or emulators. The am start command launches an Activity by its package and class name.

Flag

Reveal flag

picoCTF{pining.for.the.fjords}

The password is stored as a string resource in strings.xml - readable by jadx. Enter it in the emulator to display the flag.

Key takeaway

Android APKs are ZIP archives containing DEX bytecode and XML resources, both of which are fully recoverable by decompilers like jadx and apktool. Secrets stored in strings.xml, hardcoded in Java source, or embedded as constants in DEX are not protected at all; they are simply one tool invocation away from being read. Secrets that must live on a device should be fetched at runtime from a server that performs real authentication, not bundled into the app package.

Related reading

Want more picoCTF 2019 writeups?

Useful tools for Reverse Engineering

What to try next