Information gathering

First connect an Android phone to our machine, enable developer settings and after that we can begin the investigation.

adb devices
adb install APKey.apk

Now if we open the phone we see a new app called APKey, try to log in with any username and password, it will say Wrong Credentials! Open the apk with jadx-gui and decompile it. Under the Resources directory we see a file called AndroidManifest.xml, this is the “entrypoint” of every android apk.

In the AndroidManifest.xml if we double click on the MainActivity it will redirect to where it’s declared. It’s a big file, but the important part is from line 36 to line 67.

try {
    if (MainActivity.this.f928c.getText().toString().equals("admin")) {
        MainActivity mainActivity = MainActivity.this;
        b bVar = mainActivity.e;
        String obj = mainActivity.d.getText().toString();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(obj.getBytes());
            byte[] digest = messageDigest.digest();
            StringBuffer stringBuffer = new StringBuffer();
            for (byte b2 : digest) {
                stringBuffer.append(Integer.toHexString(b2 & 255));
            }
            str = stringBuffer.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            str = "";
        }
        if (str.equals("a2a3d412e92d896134d9c9126d756f")) {
            Context applicationContext = MainActivity.this.getApplicationContext();
            MainActivity mainActivity2 = MainActivity.this;
            b bVar2 = mainActivity2.e;
            g gVar = mainActivity2.f;
            makeText = Toast.makeText(applicationContext, b.a(g.a()), 1);
            makeText.show();
        }
    }
    makeText = Toast.makeText(MainActivity.this.getApplicationContext(), "Wrong Credentials!", 0);
    makeText.show();
} catch (Exception e2) {
    e2.printStackTrace();
}

Planning

Now we know the username is admin, but still don’t know the password. The easiest way to solve this is to patch the apk.
We have
if (str.equals("a2a3d412e92d896134d9c9126d756f")) {}
And we want
if (!str.equals("a2a3d412e92d896134d9c9126d756f")) {}

Exploiting

First we have to decompile the apk to smali(it’s the assembly of Android)
apktool d APKey.apk
Now search where is the hash stored among the smali files using grep

$ grep -rwn "a2a3d412e92d896134d9c9126d756f"
APKey/smali/com/example/apkey/MainActivity$a.smali:141:    const-string v1, "a2a3d412e92d896134d9c9126d756f"

This is how the important part looks like

:goto_1
const-string v1, "a2a3d412e92d896134d9c9126d756f"

.line 2
invoke-virtual {p1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result p1

if-eqz p1, :cond_1

The last line is what we need, if-eqz is bacically if equal, but we need the if not equal condition which is if-nez. Edit it with any editor and rebuild the apk.

apktool b APKey -o mod_APKey.apk

Before installing the apk we need to sign it due the apk changed, the previous certificate is invalid.
First create a keystore for signing.

  • Just press enter everywhere where it ask for information, except where the prompt is [no]:, here we have to type yes.
keytool -genkey -v -keystore mod-apkey-release.keystore -alias mod_apkey -keyalg RSA -keysize 2048 -validity 10000

Sign the apk

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore mod-apkey-release.keystore mod_APKey.apk mod_apkey

Install the newly created and signed apk

adb install mod_APKey.apk

If we reopen the apk on the phone and use admin as username and anything as password the flag will pop up.

Happy hacking!