[SharifCTF] REV300 Catch Me If You Can

This challenge was pretty intresting since I didn’t foud the flag in the first 30 seconds like the 3 previous one.
Okay, first things ou can download the sample here : Login.apk.tar.xz

Right, an APK ! an Android Package !

Thirst thing I did i to disassemble it, with dex2jar and jd-gui.

So get a look at the first class ( you can see the ):

package sharif.cert.ctf;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;

class a
implements View.OnClickListener {
    a(MainActivity paramMainActivity) {}

    public void onClick(View paramView) {
        new String(" ");
        paramView = this.a.b.getText().toString(); // Retrieve user input
        paramView = this.a.a(paramView);
        int i = this.a.processObject(paramView); // Call a strange method (processObject())
        if ((i == 1) && (this.a.e != "unknown")) {
            this.a.c.setText("Congratulations!");
        }
        if ((i == 1) && (this.a.e == "unknown")) {
            this.a.c.setText("Just keep Trying :-)");
        }
        if (i == 0) {
            this.a.c.setText("Just keep Trying :-)");
        }
    }
}

We can see that the processObject() method is not declared inside all the class we found .. But look at this class :

package sharif.cert.ctf;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity
extends Activity {
    Button a;
    EditText b;
    TextView c;
    int d = 123;
    String e = "Code";

    static {
        System.loadLibrary("validation"); // What is this ?
    }

    public String a(String paramString) {
        return new HidingUtil().hide(paramString); // get a look at HidingUtils()
    }

    protected void onCreate(Bundle paramBundle) {
        super.onCreate(paramBundle);
        setContentView(2130968600);
        this.a = ((Button) findViewById(2131492942));
        this.b = ((EditText) findViewById(2131492941));
        this.c = ((TextView) findViewById(2131492943));
        this.e = Build.SERIAL;
        this.a.setOnClickListener(new a(this));
    }

    public native int processObject(String paramString);
}

Okay what is loadLibrary ? by looking at the fabulous Internet, I found some documentation about Loading native code to an Android Mobile Application.

So look at the HidingUtils code :


#include <string.h>
#include <jni.h>
#include "Base64Util.h"
#include <android/log.h>

static unsigned char passwordKey[] = "My_S3cr3t_P@\$\$W0rD";

void xor_value_with_key(const char* value, char* xorOutput){
int i = 0;
while(value[i] != '\0'){
int offset = i % sizeof(passwordKey);
xorOutput[i] = value[i] ^ passwordKey[offset];
i++;
}
}


/**
 * com.apothesource.hidingpasswords.HidingUtil.hide
 *
 * This function uses a hard-coded password to XOR hide (encrypt) a provided message.
 *
 */
const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0);

    char xorOutput[BUFFFERLEN + 1] = "";
    xor_value_with_key(nativeString, xorOutput);

    char encodedoutput[BUFFFERLEN + 1] = "";

    Base64Encode(xorOutput, encodedoutput, BUFFFERLEN);

    (*env)->ReleaseStringUTFChars(env, javaString, nativeString);

    return (*env)->NewStringUTF(env, encodedoutput);

}


/*
 * com.apothesource.hidingpasswords.HidingUtil.unhide
 *
 * This function uses a hard-coded password to XOR unhide (decrypt) a provided message.
 *
 * jstring Java_com_apothesource_hidingpasswords_HidingUtil_unhide(JNIEnv_ env, jobject thiz,
 * jstring javaString) {
 */
  const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0);

      char decodedoutput[BUFFFERLEN + 1] = "";

      Base64Decode(nativeString, decodedoutput, BUFFFERLEN);

      char xorOutput[BUFFFERLEN + 1] = "";
      xor_value_with_key(decodedoutput, xorOutput);

      (*env)->ReleaseStringUTFChars(env, javaString, nativeString);

      return (*env)->NewStringUTF(env, xorOutput);

  }

A Simple xor function sets tho ! So now we know that the java application contains some .so for HidingUtils.

I did a simple binwalk extracting and I found something intresting (by extracting Login.apk with binwalk):

[sakiir@SakiiR-PC test]$ file _Login.apk.extracted/lib/x86_64/libhidingutil.so
_Login.apk.extracted/lib/x86_64/libhidingutil.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=95bfd010a331f19445de63db36939c216aa32263, stripped

When I looked to the binary strings I found something relative to the encryption routine :

$ strings _Login.apk.extracted/lib/x86_64/libhidingutil.so


[...]
AUATI
[]A\A]A^A_
My_S3cr3t_P@$$W0rD
fx1uagMGQQMWOWhyFBxnBUdzN35NPWYHUBQHRmozeEY=
;*3$"
GCC: (GNU) 4.9.x 20150123 (prerelease)
gold 1.11
.shstrtab
.note.gnu.build-id
.dynsym
.dynstr
[...]

You can see that right after the Xor Encryption Key ( My_S3cr3t_P@$$W0rD ), a base64 string is present ! we have to find out why !

$ echo "fx1uagMGQQMWOWhyFBxnBUdzN35NPWYHUBQHRmozeEY=" | base64 -d | xxd

00000000: 7f1d 6e6a 0306 4103 1639 6872 141c 6705  ..nj..A..9hr..g.
00000010: 4773 377e 4d3d 6607 5014 0746 6a33 7846  Gs7~M=f.P..Fj3xF

mmmh nothing readable, let’s decrypt it with the super secret key ( My_S3cr3t_P@$$W0rD ) :

#!/usr/bin/python2

key = "My_S3cr3t_P@\$\$W0rD\x00"
flag = "fx1uagMGQQMWOWhyFBxnBUdzN35NPWYHUBQHRmozeEY=".decode("base64")

out = ""
i = 0
for c in flag:
out += chr(ord(c) ^ ord(key[i % len(key)]))
i += 1

print "SharifCTF{" + out + "}"

This code give us the flag ;)