Android
拿到 pinstore.apk使用JEB开始分析
MainActivity
代码从输入框获取输入数据v2,再经过getHash()函数处理,处理后的内容v3再和从数据库里通过fetchPin()函数得到的v5进行比较,相同的话将会进入SecretDisplay组件,这个Activity组件是非导出的,这一点从Manifest清单里可以看到。
因此,首先跟到getHash()函数里,从下图的代码中能看到,输入的字符串pin经过SHA-1哈希之后(Byte[])转换为Hex格式。那么我就可以到数据库里找到密文解密,从而破解pin码。
从apk里导出pinlock.db,pin码的密文:
d8531a519b3d4dfebece0259f90b466a23efc57b
SHA-1解密后为:7498
破解后进入SecretDisplay,查看其反编译代码
可以看到代码通过fetchSecret()从secretsDBv1里获取数据并解密,解密后的内容显示在应用上
但是这里的内容并不是flag,进入CryptoUtilities类,看到这里的getKey()的参数是有版本区别的
再从数据库文件里看到secretsDBv2的表,可以编写解密代码,将DBv2里的密文解出来,兴许就能得到flag。
Android Studio里编写解密代码,getKey()函数里传入v2(只要不等于v1都可以)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
String cipherflag = "hcsvUnln5jMdw3GeI4o/txB5vaEf1PFAnKQ3kPsRW2o5rR0a1JE54d0BLkzXPtqB"; String cipherflag2 = "Bi528nDlNBcX9BcCC+ZqGQo1Oz01+GOWSmvxRj7jg1g=";
try{ String flag = decrypt(cipherflag2); Log.i("Leon",flag); }catch (Exception e){ Log.i("Leon","GG"); }
}
public String decrypt(String arg6) throws Exception {
String pin = "7498"; SecretKeySpec key = getKey("v2"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
byte[] v0 = Base64.decode(arg6.getBytes(), 2); Log.d("Status", v0.toString()); cipher.init(2, key); return new String(cipher.doFinal(v0), "UTF-8"); }
public SecretKeySpec getKey(String arg12) throws Exception { SecretKeySpec v2; String pin = "7498"; if(arg12.equalsIgnoreCase("v1")) { Log.d("Version", arg12); v2 = new SecretKeySpec(Arrays.copyOf(MessageDigest.getInstance("SHA-1").digest("t0ps3kr3tk3y".getBytes("UTF-8")), 16), "AES"); } else { Log.d("Version", arg12); v2 = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(new PBEKeySpec(pin.toCharArray(), "SampleSalt".getBytes(), 1000, 128)).getEncoded(), "AES"); }
return v2; }
}
|
得到flag