Android/InjuredAndroid

FLAG SEVEN - SQLITE

Analysis

Code

onCreate

public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView((int) R.layout.activity_flag_seven_sqlite);
        C((Toolbar) findViewById(R.id.toolbar));
        j.g.a(this);
        H();
        ((FloatingActionButton) findViewById(R.id.fab)).setOnClickListener(new a(this));
        SQLiteDatabase writableDatabase = this.u.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("title", Base64.decode("VGhlIGZsYWcgaGFzaCE=", 0));
        contentValues.put("subtitle", Base64.decode("MmFiOTYzOTBjN2RiZTM0MzlkZTc0ZDBjOWIwYjE3Njc=", 0));
        writableDatabase.insert("Thisisatest", (String) null, contentValues);
        contentValues.put("title", Base64.decode("VGhlIGZsYWcgaXMgYWxzbyBhIHBhc3N3b3JkIQ==", 0));
        contentValues.put("subtitle", h.c());
        writableDatabase.insert("Thisisatest", (String) null, contentValues);
    }

onCreate함수를 보면 다음과 같은 역할을 한다.

  • SQLiteDatabase 클래스를 사용하여 데이터 베이스를 생성한다
  • Thisisatest 데이터 베이스의 title과 subtitle에 base64로 인코딩 된 값을 디코딩하여 넣어준다.
  • 마지막 subtitle은 h 클래스의 c 함수 리턴값을 넣어준다.

 

submitFlag

public final void submitFlag(View view) {
        EditText editText = (EditText) findViewById(R.id.editText8);
        d.m.b.d.b(editText, "editText8");
        String obj = editText.getText().toString();
        EditText editText2 = (EditText) findViewById(R.id.editText7);
        d.m.b.d.b(editText2, "editText7");
        String obj2 = editText2.getText().toString();
        j jVar = new j();
        String c2 = jVar.c("flagSevenEncrypted", "");
        String c3 = jVar.c("flagSevenPasswordEncrypted", "");
        if (!d.m.b.d.a(obj, c2) || !d.m.b.d.a(obj2, c3)) {
            Toast.makeText(this, "Try again! :D", 0).show();
            return;
        }
        FlagsOverview.E = true;
        j jVar2 = new j();
        Context applicationContext = getApplicationContext();
        d.m.b.d.b(applicationContext, "applicationContext");
        jVar2.b(applicationContext, "flagSevenButtonColor", true);
        F();
    }

public final class j extends Application {
        private final SharedPreferences e;

        public final String c(String str, String str2) {
        d.f(str, "s"); // f 함수는 첫번쨰 인자 값이 null인지 확인한다.
        d.f(str2, "s1");
        return this.e.getString(str, str2);
    }
}

public class d {
    public static boolean a(Object obj, Object obj2) {
        return obj == null ? obj2 == null : obj.equals(obj2);
    }
}

submitFlag함수를 보면 다음과 같은 역할을 한다.

  • 사용자에게 입력받은 값을 각각 obj, obj2에 string 형태로 저장한다.
  • SharedPreference를 사용하여 각각 c2, c3에 저장된 값을 가져온다.
  • d클래스 a 함수에 각각 (obj, c2), (obj2, c3)값을 비교하여 만약 둘 다 값이 같다면 넘어가고 그렇지 않다면 리턴으로 제외시킨다.

여기서 문제는 base64로 인코딩 된 민감한 정보를 코드상에 노출한 다는 점과 사용자가 확인할 수 있는 데이터 베이스에 저장한다는 점이다.

 

Exploit

데이터 베이스는 /data/data/b3nac.injuredandroid/databases 에서 확인할 수 있다.

 

파일을 내보내기 위해 tar 명령어를 사용하여 db.tar로 만든 후 /storage/emulator/0/Download로 파일을 옮겨준다. (파일을 옮겨주는 이유는 adb pull로 파일을 가져올 때 기존 경로는 권한 문제로 가져올 수 없기 때문에 옮겨주는 것이다)

 

옮긴 후 adb pull을 사용하여 파일을 꺼내 준다.

 

이후 압축을 풀어주면 다음과 같이 데이터 베이스 파일을 가져올 수 있다.

 

추출한 데이터 베이스 파일을 열어준 후 Thisistest 테이블을 확인하면 다음과 같이 값을 확인할 수 있다.

 

이후 각각의 값을 MD5와 ROT47로 해독하면 flag와 password를 알아낼 수 있다.

2ab96390c7dbe3439de74d0c9b0b1767 - MD5 Decrpytion ⇒ hunter2

 

 

9EEADi^^:?;FC652?5C@:5]7:C632D6:@]4@>^DB=:E6];D@? - ROT47 Decoding ⇒ https://injuredandroid.firebaseio.com/sqlite.json

 

 

마지막으로 알아낸 값을 입력해주면 문제를 해결할 수 있다.

 

Reference

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

FLAG SIX - Login 3  (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