Computer:

Craft:

CTF writeup: Finisteg

This is a CTF from BreihCTF 2025. It is a simple Android reverse engineering challenge.

The application to analyze can be found on the github of the CTF.

2025-03-15

A drawing of a blue-ish round-ish platypus with big eyes, holding a laptop. This platypus is quite cute, but I might be biased.

Tools

You need:

The Android environment is a pain to set up. Here is a tuto that explains one way to do it, but there is no guarantee it will work on your machine.

Solve

We are given an application. We can start by installing it:

adb install finisteg.apk

The app is simple; you enter some text, and it tells you if you entered the flag. To understand how it works, we can use jadx:

jadx finisteg.apk
cat finisteg/sources/com/example/finisteg/MainActivity.java

We can see that the flag is available in plain text at some point at runtime:

@Override // android.view.View.OnClickListener
public void onClick(View v) {
String userFlag = flagInput.getText().toString();
String ex = MainActivity.this.decodeBase64(MainActivity.this.extractTextFromImage(bm));
if (ex.equals(userFlag)) {
Toast.makeText(MainActivity.this, "Flag Good!", 1).show();
} else {
Toast.makeText(MainActivity.this, "Flag NOT Good...", 1).show();
}
}

We can patch the apk to print the flag:

First, we disassemble the apk with apktool:

apktool d finisteg.apk -f

Then we add the call to Log.e in smali_classes3/com/example/finisteg/MainActivity$1.smali (MainActivity$1 because the callback is implemented in an anonymous class inside MainActivity). To call Log.e, you need a tag. Here v2 is available, so we can use it for that:

--- a/finisteg/smali_classes3/com/example/finisteg/MainActivity$1.smali
+++ b/finisteg/smali_classes3/com/example/finisteg/MainActivity$1.smali
@@ -82,6 +82,10 @@

.line 37
.local v1, "ex":Ljava/lang/String;
+
+ const-string v2, "BZHCTF"
+ invoke-static {v2,v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
+
invoke-virtual {v1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v2

Then we need to repackage the apk, generate a signing key, align the apk, sign it, uninstall the previous apk, and install the new one:

apktool b finisteg -o patched_finisteg.apk
keytool -genkeypair -validity 1000 -dname "CN=SomeKey,O=SomeOne,C=FR" -keystore ToyKey.keystore -storepass Pssw0rd -keypass Pssw0rd -alias SignKey -keyalg RSA -v
zipalign -v -f 4 patched_finisteg.apk patched_finisteg.aligned.apk
apksigner sign -ks ./ToyKey.keystore --v2-signing-enabled true --in patched_finisteg.aligned.apk --out patched_finisteg.signed.apk --ks-pass pass:Pssw0rd
adb uninstall com.example.finisteg
adb install patched_finisteg.signed.apk

Then start logcat to get the log, and click “Vérifier” in the apk to trigger the code:

adb logcat -s BZHCTF
--------- beginning of main
03-15 20:26:16.273 4442 4442 E BZHCTF : BZHCTF{4PK_4ND_5tEG4N0_T0_5t4rT}