.apk
という拡張子・形式は初めて見ると思います$ xxd pinstore.apk | head -n 5 0000000: 504b 0304 1400 0808 0800 457b 4a4a 82d1 PK........E{JJ.. 0000010: 5b22 ec02 0000 2808 0000 1300 0400 416e ["....(.......An 0000020: 6472 6f69 644d 616e 6966 6573 742e 786d droidManifest.xm 0000030: 6cfe ca00 00ad 543d 6fd4 4010 7d3e df05 l.....T=o.@.}>.. 0000040: 1f26 e4f2 fd71 49a0 a088 90ce 0488 00d1 .&...qI.........
$ unzip pinstore.apk ...snip... $ ls AndroidManifest.xml assets/ classes.dex META-INF/ pinstore.apk res/ resources.arsc
assets/
→アセット, 画像とか音声とかデータres/
→いろいろなアプリで使いまわされるデータMETA-INF/
AndroidManifest.xml
→アプリに関する情報(識別子、バージョンetc)resources.arsc
→メッセージなどに使う文字列classes.dex
→動作させるための.jar
(後述)が入っているDEX形式のファイル.class
という拡張子を持つバイトコードに変換(コンパイル)しますclasses.dex
内の.class
(→バイトコード)を見てみます$ /path/to/dex2jar-2.0/d2j-dex2jar.sh classes.dex
.jar
ファイルで、これも正体はZIPです$ unzip classes-dex2jar.jar $ cd pinlock/ctf/pinlock/com/pinstore/ $ ls BuildConfig.class MainActivity.class R.class ...
*.class
のようにするとそこにあるすべての.class
ファイルを指定できます$ /path/to/jad *.class
.jad
がいろいろ生成されますね、これがデコンパイル結果ですMainActivity.jad
を読んでみましょうpublic void onClick(View view) { String s; String s2; s2 = pinEditText.getText().toString(); view = null; s = null; String s1 = (new DatabaseUtilities(getApplicationContext())).fetchPin(); view = s1; _L1: s1 = CryptoUtilities.getHash(s2); s = s1; _L2: Object obj; if(view.equalsIgnoreCase(s)) { view = new Intent(MainActivity.this, pinlock/ctf/pinlock/com/pinstore/SecretDisplay); view.putExtra("pin", s2); startActivity(view); return; } else { pinEditText.setText(""); Toast.makeText(MainActivity.this, "Incorrect Pin, try again", 1).show(); return; }
DatabaseUtilities
から取得した文字列を比較していますねSecretDisplay
にpinを渡して処理を移動していますSecretDisplay.jad
を見てみましょうString s = getIntent().getStringExtra("pin"); try { DatabaseUtilities databaseutilities = new DatabaseUtilities(getApplicationContext()); textview.setText((new CryptoUtilities("v1", s)).decrypt(databaseutilities.fetchSecret())); } catch (Exception exception) { Log.e("Pinlock", "exception", exception); } Toast.makeText(bundle, s, 1);
CryptoUtilities
なるものを生成してから、DatabaseUtilities
で取り出してからdecrypt(=復号・解読)していますねDatabaseUtilities
の内容も読んでみましょうDatabaseUtilities
public String fetchPin() { // MainActivityから呼び出される openDB(); Cursor cursor = db.rawQuery("SELECT pin FROM pinDB", null); // pinDBテーブルからデータを取り出す ... return s; } public String fetchSecret() { // SecretDisplayから呼び出される openDB(); Cursor cursor = db.rawQuery("SELECT entry FROM secretsDBv1", null); // secretsDBv1テーブルからデータを取り出す ... return s; } ... private static String dbName = "pinlock.db"; private static String pathToDB = "/data/data/pinlock.ctf.pinlock.com.pinstore/databases/";
- データベースからいろいろ読み出しているみたいです
pinlock.db
というのがデータベースのファイルっぽいので、中身のデータを取り出してみましょうfind
コマンドでファイルを検索できます$ find -name pinlock.db ./assets/pinlock.db $ sqlitebrowser ./assets/pinlock.db &
SELECT * FROM pinDB
などはSQL言語で書かれたデータベースを操作するためのコードです