首先先用jadx反編譯出源代碼,可以看到目錄結構
從這里就可以知道我們只需查看pinlock.ctf.pinlock.com.pinstore目錄下的代碼即可
先從MainActivity看起
從源代碼我們可以知道pinFormDB是數據庫中存儲的密碼、hashOfEnteredPin屬於我們輸入的密碼加密后的密文,在這里我們可以修改if的判斷條件
接下來通過apktool工具對apk文件進行反編譯得到smail代碼
分別找到pinFormDB對應的是v5,hashOfEnteredPin對應的是v3
然后接下來找到兩個參數在一起被調用的地方
通過修改藍色方框內的內容:if-eqz => if-nez
注:if-eqz:如果vAA為0則跳轉
if-nez:如果VAA不為0則跳轉
於是我們在只要輸不出正確的密碼就可以直接讀取數據,結果如下圖
可惜這不是我們想要的flag,所以恢復原來的smail,繼續分析源代碼,
在這里我們找到一個Toast,Toast是用來顯示消息的,我們可以修改smail源碼讓密碼爆出來(v5是從數據庫中讀取的密文pinFromDB,v7是密碼輸入錯誤提示信息"Incorrect Pin, try again")
通過修改藍色方框內的內容:v7 => v5
結果如下圖,
得到加密的密碼密文:d8531a519b3d4dfebece0259f90b466a23efc57b
MD5解密得:7498
可惜也不是我們想要的flag。
在這里還是話費了我大量時間來找flag位置,
這里是后知后覺的pinlocak.db,我們用navicat for sqlite打開,這里我們可以發現他有pinDB、secretsDBv1和secretsDBv2
然而在源代碼中我們查看,發現我們只讀取過secretsDBv1和pinDB
//[MainActivity.java] pinFromDB = new DatabaseUtilities(MainActivity.this.getApplicationContext()).fetchPin(); //*********************** Intent intent = new Intent(MainActivity.this, SecretDisplay.class); intent.putExtra("pin", enteredPin); MainActivity.this.startActivity(intent);
//[MainActivity.java] tv.setText(New CryptoUtilities("v1", pin).decrypt(new DatabaseUtilities(getApplicationContext()).fetchSecret()));
所以我們更可以讀取secretsDBv2數據看看,但是要注意一個問題
我們可以發現從數據庫中讀取數據的解密方式不一樣
所以我們需要修改兩處位置:
位置一:在DatabaseUtilities.smail里找到字符串”SELECT entry FROM secretsDBv1”
通過修改藍色方框內的內容:
SELECT entry FROM secretsDBv1 -> SELECT entry FROM secretsDBv2
位置二:在SecretDisplay.smail里找到字符串”v1”(這里也可以同上面一樣修改if條件嗎;"v1"字符串好找,這里就改v1了)
通過修改藍色方框內的內容:
v1 -> v2 (這里可以是任意非v1內容)
然后打包回編譯,簽名apk后,我們就可以得到flag了