Category: Mobile Security

You can download the Mobile Security Challenge, along with all the challenges for the 2016 Greek Qualifier CTF of European Cybersecurity Challenge, in this link. More details on the Greek ECSC 2016 Qualifier CTF event can be found here.

Points: 60

Challenge designer: Kolovos

Description: > Your goal is to find the flag hidden within the communication with the server. There is no need to hammer the server in order to get the flag.

     ooo           '*`           ###
    (o o)         (o o)         (o o)
ooO--(_)--Ooo-ooO--(_)--Ooo-ooO--(_)--Ooo-

Write-up

First step is to extract the Java code from the provided apk file. We use the flag --deobf to avoid overloaded functions in jadx output and get some unique class and function names that we can reference and understand easier.

❯❯❯ d2j-dex2jar.sh otp.apk
❯❯❯ jadx --deobf otp.jar

The application has a button that when clicked executes function C0312e.m2871a().

/ctf/cirrus/otp/C0312e.java

public static String m2871a() {
    String str;
    JSONObject b;
    String str2 = "https://token-1321.appspot.com/getToken?";
    String bigInteger = new BigInteger(130, new SecureRandom()).toString(10);
    String str3 = "";
    try {
        hash = new String(Hex.encodeHex(MessageDigest.getInstance("MD5").digest(("type=otp&generate=new&challenge=" + bigInteger + "&magic=y0l0").getBytes())));
        try {
            Log.i("INFO", "hash=" + hash);
        } catch (NoSuchAlgorithmException e) {
            Log.i("ERROR", "NoSuchAlgorithmException");
            b = C0312e.getJsonObjectFromString(C0312e.m2873a(str2 + ("type=otp&challenge=" + bigInteger + "&hash=" + hash)));
            str3 = "";
            return b.getString("token");
        }
    } catch (NoSuchAlgorithmException e2) {
        hash = str3;
        Log.i("ERROR", "NoSuchAlgorithmException");
        b = C0312e.getJsonObjectFromString(C0312e.m2873a(str2 + ("type=otp&challenge=" + bigInteger + "&hash=" + hash)));
        str3 = "";
        return b.getString("token");
    }
    b = C0312e.getJsonObjectFromString(C0312e.m2873a(str2 + ("type=otp&challenge=" + bigInteger + "&hash=" + hash)));
    str3 = "";
    try {
        return b.getString("token");
    } catch (JSONException e3) {
        Log.i("ERROR", "Token not found");
        return "There was an error retrieving the token.";
    }
}

The application first generates a random BigInteger (130 bits/16 bytes) which is used as the challenge in the actions to follow. There is also a static magic string (y0l0) and a type (otp) which all together are put in a string and used to generate a MD5 hash.

hash = new String(
    Hex.encodeHex(
        MessageDigest.getInstance("MD5")
            .digest(("type=otp&generate=new&challenge=" + bigInteger + "&magic=y0l0").getBytes())));

We can replay the same actions using Python and generate the MD5 digest ourselves:

import random
import hashlib

challenge = random.getrandbits(130)
secret_request = 'type=otp&generate=new&challenge=%s&magic=y0l0' % str(challenge)
secret_hash = hashlib.md5(secret_request).hexdigest()
print 'Challenge: %s' % challenge
print 'Hash:      %s' % secret_hash

The final step is to use the challenge and the hash in a GET request to generate a new token and get our flag. All steps have been combined in the following Python script:

import random
import hashlib
from pwn import *

HOST = 'token-1321.appspot.com'

challenge = random.getrandbits(130)
log.success('Challenge: %s' % challenge)

secret_request = 'type=otp&generate=new&challenge=%s&magic=y0l0' % str(challenge)
secret_hash = hashlib.md5(secret_request).hexdigest()
log.success('Hash: %s' % secret_hash)

r = remote(HOST, 443, ssl=True)
r.send('GET /getToken?type=otp&generate=netype=otp&challenge=%s&hash=%s HTTP/1.1\r\nHost: %s\r\n\r\n' % (challenge, secret_hash, HOST))
resp = r.recv().splitlines()
flag = [f for f in resp if 'flag' in f][0]
log.success(flag)

r.close()
❯❯❯ python solution.py
[+] Challenge: 359664723468245819351269767034398323045
[+] Hash: e5b1858b72939c47ad1ce90f36d58dbe
[+] Opening connection to token-1321.appspot.com on port 443: Done
[+] {"token": "6324", "flag": "N0tV3ryRand0mStr1ng"}
[*] Closed connection to token-1321.appspot.com port 443

The flag is: > N0tV3ryRand0mStr1ng

# echo 7eamnull

Share This

Share this post with your friends!