/** SakiiR */

A Random CTF Player from Hexpresso


Blog | About

[SharifCTF] REV300 Catch Me If You Can

03 Jan 2017 | reverse

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.
 */
jstring Java_com_apothesource_hidingpasswords_HidingUtil_hide(JNIEnv* env, jobject thiz, jstring 
javaString) {
    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 ;)


Newer ·

[insomnihack 2017 Teaser] Web50 Smarttomcat

Web50 SmartTomcat APP