Sunday 7 February 2016

CTF Writeup - Sharif University CTF 2016 - Android App (RE 100)


  • Name - Android App
  • Category - Reverse Engineering
  • Points - 100
  • Description - Find the Flag!!
  • Binary - Download here

This challenge is a good exercise for those of you who would like to start REing android apps. Once again the application accepts a serial number and validates it:


Extract the apk file and open classes.dex with Jadx. You can use dex2jar and jdgui for this but I found that Jadx gives better results. The part we're interested in resides in the button's listener, onClick() in class a:

public void onClick(View view) {
    String str = new String(" ");
    str = this.a.b.getText().toString();
    Log.v("EditText", this.a.b.getText().toString());
    String str2 = new String("");
    int processObjectArrayFromNative = this.a.processObjectArrayFromNative(str);
    int IsCorrect = this.a.IsCorrect(str);
    str = new StringBuilder(String.valueOf(this.a.d + processObjectArrayFromNative)).append(" ").toString();
    try {
        MessageDigest instance = MessageDigest.getInstance("MD5");
        instance.update(str.getBytes());
        byte[] digest = instance.digest();
        StringBuffer stringBuffer = new StringBuffer();
        for (byte b : digest) {
            stringBuffer.append(Integer.toString((b & 255) + 256, 16).substring(1));
        }
        if (IsCorrect == 1 && this.a.e != "unknown") {
            this.a.c.setText("Sharif_CTF(" + stringBuffer.toString() + ")");
        }
        if (IsCorrect == 1 && this.a.e == "unknown") {
            this.a.c.setText("Just keep Trying :-)");
        }
        if (IsCorrect == 0) {
            this.a.c.setText("Just keep Trying :-)");
        }
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

Our input is read from the textfield (line 3) and passed to the IsCorrect() function (line 7). Unfortunately this function is part of the adnjni library (\lib\armeabi folder); it would've been too easy if it was written in Java. Load the library in IDA and locate the function Java_com_example_ctf2_MainActivity_IsCorrect(). The first section looks like this:

v9 = (char *)(*(int (**)(void))(*(_DWORD *)a1 + 676))();
v12 = 101;
v13 = 102;
v14 = 53;
v15 = 55;
v16 = 102;
v17 = 51;
v18 = 102;
v19 = 101;
v20 = 51;
v21 = 99;
v22 = 102;
v23 = 54;
v24 = 48;
v25 = 51;
v26 = 99;
v27 = 48;
v28 = 51;
v29 = 56;
v30 = 57;
v31 = 48;
v32 = 101;
v33 = 101;
v34 = 53;
v35 = 56;
v36 = 56;
v37 = 56;
v38 = 55;
v39 = 56;
v40 = 99;
v41 = 48;
v42 = 101;
v43 = 99;
v44 = 0;
v4 = 0;
v45 = 53;
v10 = j_j_strcmp(v9, &v12);

Notice that at the bottom (line 37), 2 strings are being compared. Variable v9 contains our input string and variable v12 contains the string shown on lines 2 to 34. Once again, converting from decimal to ASCII we get ef57f3fe3cf603c03890ee588878c0ec.

And hence:

No comments:

Post a Comment