描述
A secret string is hidden somewhere in this app. Find a way to extract it.
目标
找到密码
APK 下载
题解
首先打开 APP 看一下,可以看到是需要输入注册码来进行注册,但是检测到了 root,需要先过 root 检测。
在 GitHub 上有个脚本可以过很多 root 检测 https://github.com/AshenOneYe/FridaAntiRootDetection,用这个脚本就可以过这个 APP 的 root 检测,不过还是看看具体代码中怎么过吧。 Jadx-GUI 打开找到 root 检测的位置,发现用到了 3 个函数,当 3 个函数都返回 true 时就可以正常使用 APP。
点进去发现 3 个函数都在一个类中,只要将 3 个函数都改为永远返回 true 就行,可以直接修改 smali 或者 hook,hook 方便一些。
写好 hook 的代码,使用 frida 重启注入 frida -U --no-pause -f owasp.mstg.uncrackable1 -l crack.js
function passRoot() {
Java.perform(function() {
let c = Java.use("sg.vantagepoint.a.c");
c["a"].implementation = function () {
console.log(`c.a is called`);
return false;
};
c["b"].implementation = function () {
console.log(`c.b is called`);
return false;
};
c["c"].implementation = function () {
return false;
};
})
}
function main() {
passRoot();
}
setImmediate(main);
打开后 APP 就可以正常使用,不会提示 root 了。
再找到验证密码的地方,看到是在 verify() 方法中,将用户输入的文本传入 a.a() 方法中进行检查。
进入 a.a() 方法,可以看到加密的方法还是比较简单的,本地还原一下就行。
将加密函数进行本地还原,输出结果为 I want to believe
from base64 import b64decode
from Crypto.Cipher import AES
def aes_decrypt(key_hex: str, data_base64: str) -> bytes:
key = bytes.fromhex(key_hex)
data = b64decode(data_base64)
cipher = AES.new(key, AES.MODE_ECB)
decrypted_data = cipher.decrypt(data)
pad_len = decrypted_data[-1]
decrypted_data = decrypted_data[:-pad_len]
return decrypted_data
def get_string() -> str:
try:
decrypted_data = aes_decrypt("8d127684cbc37c17616d806cf50473cc", "5UJiFctbmgbDoLXmpL12mkno8HT4Lv8dlat8FxR2GOc=")
except Exception as e:
print(f"AES error: {str(e)}")
decrypted_data = b''
return decrypted_data.decode()
print(get_string())
# output: I want to believe
将密码输入 APP,密码正确,密码为 I want to believe