SSL Pinning 定位 hook
🔍 Hook
File.$init(File, String),定位证书绑定(SSL Pinning)的关键代码。
📎 源码在线查看:
script.js(Pinning locator)
作用
当 App 读取 cacert 文件做证书校验,且调用栈里出现 X509TrustManagerExtensions.checkServerTrusted 时,认为这是 pinning 校验点,把文件路径与调用栈 send 回 Python,帮助逆向定位绑定逻辑。
实现
javascript
Java.use("java.io.File").$init.overload('java.io.File', 'java.lang.String').implementation =
function (file, cert) {
var result = this.$init(file, cert)
var stack = Java.use("android.util.Log").getStackTraceString(
Java.use("java.lang.Throwable").$new());
if (file.getPath().indexOf("cacert") >= 0 &&
stack.indexOf("X509TrustManagerExtensions.checkServerTrusted") >= 0) {
var message = {};
message["function"] = "SSLpinning position locator => " + file.getPath() + " " + cert;
message["stack"] = stack;
var data = Memory.alloc(1);
send(message, Memory.readByteArray(data, 1))
}
return result;
}双条件过滤
javascript
if (file.getPath().indexOf("cacert") >= 0 &&
stack.indexOf("X509TrustManagerExtensions.checkServerTrusted") >= 0)只有同时满足两个条件才上报:
| 条件 | 含义 |
|---|---|
路径含 cacert | App 在读自定义 CA 证书文件(pinning 常见做法:内置固定证书) |
栈含 checkServerTrusted | 调用栈经过证书校验逻辑 |
双条件避免误报——单纯读 cacert 不一定是 pinning,单纯过 checkServerTrusted 也不一定是文件型 pinning。
事件 message
function: "SSLpinning position locator => /data/.../cacert.bks mycert"
stack: "at com.app.security.Pinning.checkServerTrusted(Pinning.java:88)\n..."stack 直接指出 App 哪个类哪个方法在做证书绑定——逆向时据此定位绑定逻辑,进而绕过。
r0capture 不绕过 pinning,只定位
注意区分
r0capture 的 SSL hook 在 SSL_read/SSL_write 层,本身就无视 pinning(pinning 在 hook 点之上,校验失败也照样能 hook 到明文)。这个 hook 的目的是定位 pinning 代码位置,便于逆向研究 App 的绑定实现,不是为了抓包而绕过。
1 字节占位
与证书导出一样,用 Memory.alloc(1) + readByteArray(data, 1) 发 1 字节 data,触发 Python 端事件分支。