Android/InjuredAndroid

FLAG SIX - Login 3

Analysis

Code

submitFlag

public final void submitFlag(View view) {
        EditText editText = (EditText) findViewById(R.id.editText3);
        d.b(editText, "editText3");
        if (d.a(editText.getText().toString(), k.a("k3FElEG9lnoWbOateGhj5pX6QsXRNJKh///8Jxi8KXW7iDpk2xRxhQ=="))) {
            Intent intent = new Intent(this, FlagOneSuccess.class);
            FlagsOverview.D = true;
            new j().b(this, "flagSixButtonColor", true);
            startActivity(intent);
        }
}

public class k {

    private static final byte[] f1917a = h.b();

    public static String a(String str) {
        if (c(str)) {
            try {
                SecretKey generateSecret = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(f1917a));
                byte[] decode = Base64.decode(str, 0);
                Cipher instance = Cipher.getInstance("DES");
                instance.init(2, generateSecret);
                return new String(instance.doFinal(decode));
            } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Not a string!");
            return str;
        }
    }
        ...
}

submitFlag함수는 다음과 같은 순서로 진행한다.

  1. editText3 값을 이용하여 사용자가 입력한 값을 가져온다.
  2. 값 비교를 위해 d 클래스 a 함수에 입력받은 값을 문자열로 변환한 값과 암호화된 값("k3FElEG9lnoWbOateGhj5pX6QsXRNJKh///8Jxi8KXW7iDpk2xRxhQ==")을 복화된 값을 인자로 넘겨준다
  3. 두 값이 같으면 FlagOneSuccess 액티비티를 활성화 시킨다.

여기서 문제점은 암호화된 문자열과 반환 값으로 복호화 값을 보내주는 함수가 모두 코드 안에 존재한다는 점이다.

 

Exploit

문제를 해결하기 위해 암호화 루틴(k클래스의 a함수)을 후킹한 후 암호화된 값을 넘겨주어 해결한다.

이를 위한 코드는 다음과 같다.

Java.perform(function x() {
    var my_class = Java.use("b3nac.injuredandroid.k");
    var string_class = Java.use("java.lang.String");

    my_class.a.overload("java.lang.String").implementation = function (args) {
        var my_string = string_class.$new("k3FElEG9lnoWbOateGhj5pX6QsXRNJKh///8Jxi8KXW7iDpk2xRxhQ==");
        console.log("original: " + args);
        var ret = this.a(my_string);
        console.log("return: " + ret);
        return ret;
    }
})
  • Java.use(ClassName) : 앱에서 사용하는 클래스와 연동되는 클래스를 선언한다.
  • java.lang.String : java.lang 패키지에 포함되어 있으며 Java에서 문자열을 사용하기 위한 String 클래스이다.
  • .overload(Type).implementation(args) : 오버로드를 할때 사용한다. 인자를 받는 함수인 경우 타입과 그에 맞는 인자를 써줘야 한다.

코드를 설명하자면 다음과 같다.

  1. 복호화 루틴이 존재하는 "b3nac.injuredandroid.k"와 String 클래스가 포함된 "Java.lang.String"을 선언한다.
  2. 복호화 루틴 함수를 오버로딩 하기 위해 그에 맞는 타입(String)과 인자를 받도록 선언한다.
  3. 암호화 문자열을 이전에 가져온 string 클래스를 사용하여 my_string에 저장한다.
  4. 복호화 함수에 암호화된 문자열을 넘겨 복호화된 문자열을 받는다.

 

스크립트를 실행하면 다음과 같이 화면을 확인할 수 있는데

 

이후 FlagSIX에 들어가서 아무 값을 입력한 후 등록을 해주면

 

다음과 같이 복호화된 문자열이 출력되는 것을 확인할 수 있다.

 

마지막으로 복호화된 문자열을 입력해주면 문제를 해결할 수 있다.

 

Reference

'Android > InjuredAndroid' 카테고리의 다른 글

FLAG SEVEN - SQLITE  (0) 2021.09.21
FLAG FOUR - Login 2  (0) 2021.09.21
FLAG THREE - RESOURCES  (0) 2021.09.21
FLAG TWO - EXPORTED ACTIVITY  (0) 2021.09.21
FLAG ONE - Login  (0) 2021.09.21