NahamCon – Mobile – Secure Safe

Secure Safe is a 100 point Mobile challenge in the NahamCon CTF. The challenge provides the secure_safe.apk file and the description This app says it secures my stuff! It's so cool!
The challenge is actually somewhat complicated, as the flag cannot be obtained by simply decompiling the apk.  Its actually an ‘encrypted’ string resource
This probably means that the encryption method will have to be reversed, but there is a twist. Running the APK in an emulator shows that a 4 digit pin code forms part of the process
The max length of the pin is only 4 digits at least, so there are only 10’000 possible combinations which can be brute forced in a few seconds.
Going through the bytecode of the MainActivity class shows that the encrypted flag, stored in p1 are passed along with the 4 digit pin stored in v0 to the a method in MainActivity$
The onClick method in turn calls the a method from the a class, passing along the flag and pin code again
The a method is actually a straight forward xor operation
So my assumption is that the pin forms a part of the key somehow. There is a method below a called doInBackground which is basically an android method that will complete a task in the background thread once its been invoked (TL;DR Async method for computation). This is the method where the hash computation and decryption actually takes place.
JEB provides an excellent decompiler, which translates the two methods into the following
public final byte[] a(byte[] arg5, byte[] arg6) {
    byte[] v0 = new byte[arg5.length];
    int v1;
    for(v1 = 0; v1 < arg5.length; ++v1) {
        v0[v1] = (byte)(arg5[v1] ^ arg6[v1 % arg6.length]);
    }
    return v0;
}


public Object doInBackground(Object[] arg7) {
    String[][] v7 = (String[][])arg7;
    String v2 = v7[0][0];
    String v7_1 = v7[0][1];
    try {
        MessageDigest v4 = MessageDigest.getInstance("SHA-1");
        v4.update("5up3r_53cur3_53cr37".getBytes("UTF-8"));
        v4.update(v7_1.getBytes("UTF-8"));
        String v7_3 = new BigInteger(1, v4.digest()).toString(16);
        return new String(this.a(Base64.decode(v2, 0), v7_3.getBytes()));
    }
    catch(NoSuchAlgorithmException | UnsupportedEncodingException v7_2) {
        v7_2.printStackTrace();
        return "Error decrypting";
    }
}

From that its really straight forward to put together a quick java app that will loop 1 to 10000 and brute force the encrypted flag. See comments in the code below for explanation.

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;




public class C3 {
    // XoR method
    public final static byte[] a(byte[] arg5, byte[] arg6) throws Exception {
        byte[] v0 = new byte[arg5.length];
        int v1;
        for(v1 = 0; v1 < arg5.length; ++v1) {
            v0[v1] = (byte)(arg5[v1] ^ arg6[v1 % arg6.length]);
        }




        return v0;
    }
    public static void main(String args[]) throws Exception {
        // byte array of the encrypted flag
        byte[] v2 = "UFhYVUt2VmdqEFALbiNXRkZvVQtTQxwSTVABe0U=".getBytes();
        // Loop from 1000 to 10000 as pin has to be 4 digits long
        for (int i = 1000; i <= 10000; i++) {
            // Print the pin code (i)
            String pin = Integer.toString(i);
            System.out.println(pin);
            // Initialize the method digest
            MessageDigest v4 = MessageDigest.getInstance("SHA-1");
            // Updates the digest using the specified array of bytes
            v4.update("5up3r_53cur3_53cr37".getBytes("UTF-8"));
            // Further updates the digest using the pin code
            v4.update(pin.getBytes("UTF-8"));
            // Create the key
            String v7_3 = new BigInteger(1, v4.digest()).toString(16);
            // Decrypt using the a method and print the result
            System.out.println(new String(a(Base64.getDecoder().decode(v2), v7_3.getBytes())));
        }
    }
}

There will only be a single correct flag, so its possible to just grep flag the stdout.

javac C3.java && java C3 | grep flag

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *