team-logo
Published on

Friday Cake — Mobile (Medium) Writeup

Authors

Friday Cake

Category: Mobile
Difficulty: Medium
Challenge Author: KyootyBella
Tags: mobile, reverse

It's Friday - your family cake night! 🍰 But when you try to order your favorite cake, you find that someone has changed the app and locked the ordering screen!

Recover the Secret Access Code and save the family's cake tradition.


Handout files

mobile_fridaycake.zip


First Part

Look at the files

There isn’t much to look at it’s a single apk file, so we need an Android emulator to run it. I used BlueStacks. The app is simple: one input field and a submit button.

1

The goal is obvious: find the valid code to unlock the flag!

This is where the reverse engineering part begins.

Reversing the App

Let’s convert the APK to Java to see what’s inside. I used dex-tools v2.4:

"C:\path\to\d2j-dex2jar.bat" -f -o "C:\path\to\FridayCake-dex2jar.jar" "C:\path\to\FridayCake.apk"

Then open the JAR in JD-GUI:

2

Click the method responsible for code verification. You’ll see it delegates to a native library: native-lib (loaded via JNI).

3

At this point we could reverse the native library, but there’s an easier way: read the secret value at runtime using Frida.

In one of a previous post I showed how to set up Frida and ADB, so here I’ll reuse that setup.

Start ADB and your Frida server (adjust paths as needed):

adb kill-server
adb start-server
adb devices

adb -s emulator-5554 shell
su root  
/.path/to/frida >/dev/null 2>&1 &

In a second terminal, run Frida with a small script:

Java.perform(function () {
  const NC = Java.use('dk.brunnerctf.fridaycake.NativeChecker');

  // Get an instance (Kotlin singleton) or create a new object
  var inst = null;
  try { inst = NC.INSTANCE.value; } catch (e) {}
  if (!inst) { inst = NC.$new(); }

  // Transformation as in Authenticator: reverse + "::CAKE::" + +2 for each character
  function transform(s) {
    var t = s.split("").reverse().join("") + "::CAKE::";
    var out = "";
    for (var i = 0; i < t.length; i++) out += String.fromCharCode(t.charCodeAt(i) + 2);
    return out;
  }

  var verify = NC.verifyCode.overload('java.lang.String');
  var getFlag = NC.getDecryptedFlag.overload();

  // Kick-start: the first verify triggers native-side decryption
  try { verify.call(inst, transform("AAAA")); } catch (e) {}

  // This is the code you need to enter in the app:
  var secret = getFlag.call(inst);
  console.log("[SECRET_CODE] " + secret);

  // (optional) verify that it passes validation:
  try {
    var ok = verify.call(inst, transform(secret));
    console.log("[VERIFY] " + ok);
  } catch (e) {
    console.log("[VERIFY_ERR] " + e);
  }
});

Here is command I used:

frida -U -f dk.brunnerctf.fridaycake -l C:\path\to\frida-script.js

Once the script runs, it prints the secret/flag to the console:

4

That’s the value you can enter in the app to unlock the cake screen (and it also serves as the flag for the challenge).

brunner{Y0u_Us3d_Fr1d4_F0r_Gr4bb1ng_Th1s_R1ght?}