UnCrackable-Level1.apk
下载并安装,打开;一上来就被检测出root权限了。
将apk丢入jeb中查看,通过ctrl + f
搜索字符串。
c.a()、c.b()、c.c()的逻辑如下图,我发现,在我的/system/bin中,确实有一个su。
方案1,粗暴的解决方案,修改dex文件并重新签名。在onCreate的第一个if处,将判断结果改成false;
1 2 3 4 5 6 7 8 9 10 11 12
| Java.perform(function(){ const root = Java.use("sg.vantagepoint.util.RootDetection"); root.checkRoot1.implementation = function(){ return false; } root.checkRoot2.implementation = function(){ return false; } root.checkRoot3.implementation = function(){ return false; } });
|
方案2,hook掉exit函数或者hook掉相关函数;
方案3,面具magisk里直接屏蔽掉UnCrackable-Level1.apk的root权限,让它检测不到root。
这里介绍一下第二个方法,js脚本如下,执行方法也如下,然后就绕过去了。
1 2 3 4 5 6 7 8 9 10
| # frida -U -f owasp.mstg.uncrackable1 -l .\uncrackable-level1.js
Java.perform(function(){ var temp = Java.use("java.lang.System"); # 获得System类 # exit是静态函数,不需要实例化后再调用 # overload指定具体的重载版本 temp.exit.overload('int').implementation = function(arg0){ console.log("Exit called with " + arg0); }; });
|

通过jeb,可以发现在类a中,函数a会根据输入的内容进行比较,随后得出是否正确的答案。

下面是写的一个js脚本,直接return true,或者通过sg.vantagepoint.a.a.a得到解密的明文。
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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| # 直接改为true Java.perform(function() { var targetClass = Java.use('sg.vantagepoint.uncrackable1.a'); targetClass.a.overload('java.lang.String').implementation = function(s) { console.log("\n[*] 拦截验证方法调用"); console.log("原始输入: " + s); var result = this.a(s); console.log("原始验证结果: " + result); console.log("[+] 强制返回 true"); return true; }; });
# 观察正确的输入 Java.perform(function() { var crypto = Java.use('sg.vantagepoint.a.a'); var checker = Java.use('sg.vantagepoint.uncrackable1.a'); checker.a.overload('java.lang.String').implementation = function(s) { var ciphertext_b64 = "5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc="; var key_bytes = [0x8D, 0x12, 0x76, 0x84, 0xCB, 0xC3, 0x7C, 0x17, 0x61, 0x6D, 0x80, 0x6C, 0xF5, 0x04, 0x73, 0xCC]; var jKey = Java.array('byte', key_bytes); var ciphertext = Java.use('android.util.Base64').decode(ciphertext_b64, 0); try { var decrypted_bytes = crypto.a(jKey, ciphertext); var plaintext = Java.use('java.lang.String').$new(decrypted_bytes); console.log("\n[+] 解密成功!Secret String: " + plaintext); } catch(e) { console.log("[-] 解密失败: " + e); } return this.a(s); }; });
|
执行,得到结果。
