Skip to content

Intentional Exercise

Difficulty: Moderate Skills: Android Flags: 1


Flag 1/1

First, we need wait until the APK is building. Download the .APK file. Decompile the .APK with apktool

apktool d level13.apk
  • The target SDK is 28 (Android 9.0).

Then, install the APK with ADB to our Android Device, I use Genymotion.

adb install level13.apk

Open the app and

So let’s order this.. When the App is open, we see an WebView:

/appRoot?&hash=61f4518d844a9bd27bb971e55a23cd6cf3a9f5ef7f46285461cf6cf135918a1a

And if we click on “Flag”, we will redirect to:

/appRoot/flagBearer

And an Invalid request message. So this made me think that the key is the URL. Well.. let’s inspect the Java source code. With jadx-gui Note: URL is your private Hacker101 instance.

MainActivity.java > onCreate

public void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.activity_main);
    WebView webView = (WebView) findViewById(R.id.webview);
    webView.setWebViewClient(new WebViewClient());
    Uri data = getIntent().getData();
    String str = "https://URL.ctf.hacker101.com/appRoot";
    String str2 = BuildConfig.FLAVOR;
    if (data != null) {
        str2 = data.toString().substring(28);
        str = "https://URL.ctf.hacker101.com/appRoot" + str2;
    }
    if (!str.contains("?")) {
        str = str + "?";
    }
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        messageDigest.update("s00p3rs3cr3tk3y".getBytes(StandardCharsets.UTF_8));
        messageDigest.update(str2.getBytes(StandardCharsets.UTF_8));
        webView.loadUrl(str + "&hash=" + String.format("%064x", new BigInteger(1, messageDigest.digest())));
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

Looking and analyzing the code, I my head this is:

str = https://URL.ctf.hacker101.com/appRoot

We can assume that str + str2 is:

https://URL.ctf.hacker101.com/appRoot/flagBearer

Because:

if (data != null) {
            str2 = data.toString().substring(28);
            str = "https://URL.ctf.hacker101.com/appRoot" + str2;
        }

And then:

if (!str.contains("?")) {
            str = str + "?";
        }

If https://URL.ctf.hacker101.com/appRoot/flagBearer no contains “?” then, add it. Until now, we have:

https://URL.ctf.hacker101.com/appRoot/flagBearer?

And in the end, we have:

try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update("s00p3rs3cr3tk3y".getBytes(StandardCharsets.UTF_8));
            messageDigest.update(str2.getBytes(StandardCharsets.UTF_8));
            webView.loadUrl(str + "&hash=" + String.format("%064x", new BigInteger(1, messageDigest.digest())));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

So, now the value of the URL is:

https://URL.ctf.hacker101.com/appRoot/flagBearer?&hash=

We have the MessageDigest instance, that use SHA-256 In first place, is s00p3rs3cr3tk3y That in SHA-256 is

61f4518d844a9bd27bb971e55a23cd6cf3a9f5ef7f46285461cf6cf135918a1a

(Remember the first URL) But the messageDigest is update with the str2 value, that is /flagBearer Then, this is the “key”:

s00p3rs3cr3tk3y/flagBearer

The SHA-256 can be calculated with this script that I made:

import hashlib

# key
key = "s00p3rs3cr3tk3y/flagBearer"

# get SHA-256
hash_sha256 = hashlib.sha256(key.encode()).hexdigest()

# print
print("[*] The hash is:", hash_sha256)
print("--------------------------------------------------------------------")
print("Then, the final URL is: https://URL.ctf.hacker101.com/appRoot/flagBearer?&hash=" + hash_sha256)

Then, the final URL is

https://URL.ctf.hacker101.com/appRoot/flagBearer?&hash=<HASH>

At this point you can check your desktop browser to get the flag. But we can try “fix” the App (or try get the Flag easily). In the MainActivity.smali code, we can replace the first URL (When the WebView is created/loaded).

.line 24
invoke-virtual {v0}, Landroid/content/Intent;->getData()Landroid/net/Uri;

move-result-object v0

const-string v1, "https://URL.ctf.hacker101.com/appRoot"

const-string v2, ""

if-eqz v0, :cond_0

.line 28

At the line 55 of the file, we can replace https://URL.ctf.hacker101.com/appRoot* to https://URL.ctf.hacker101.com/appRoot/flagBearer?&hash=HASH Then build and sign the new .APK and remove the old App, then install.

apktool b level13
apksigner sign --ks name.keystore --ks-key-alias alias --out apk.apk level13/dist/level13.apk
adb install apk.apk

And here is:

I hope you found it useful (: