首先先用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了