第十三节 绕过 SSL Pinning
(第2章 安卓逆向基础)
学习目标
学完本节,希望你能够:
- 说出 SSL Pinning (证书钉扎)是啥:应用只信任指定证书或公钥,不信任系统/用户 CA,导致抓包工具的证书不被信任,HTTPS 抓包失败。
- 理解为啥要「绕过」:在授权环境下抓包分析 API、协议、加密数据时,需要让应用接受抓包工具的 CA。
- 会用 jadx 找 CertificatePinner 、checkServerTrusted 、TrustManager 等关键字,判断应用用的哪种校验方式。
- 会用 Frida (或 Xposed)Hook OkHttp CertificatePinner.check 、X509TrustManager.checkServerTrusted 等,绕过校验后配合 Burp 等抓包(仅限授权环境)。
阅读提示 :绕过 SSL Pinning 仅限授权环境、学习与安全研究;不得对他人应用做未授权抓包或传播脚本。
常见疑问 :装了 Burp 证书为啥还是报错?因为应用做了 SSL Pinning,不信任系统 CA,需要 Hook 掉校验逻辑。
一、SSL Pinning 是啥?
SSL Pinning (证书钉扎)说白了就是:应用只信任自己绑定的证书或公钥 ,不信任系统/用户安装的 CA(如 Burp、Charles 的证书),这样即使用户装了抓包 CA,应用也会报「证书错误」、拒绝建立 HTTPS。目的是防中间人攻击(MITM)。
为啥要绕过?(仅限授权环境)
在授权环境下做安全研究、协议分析、API 分析时,需要看到 HTTPS 明文,就要让应用「接受」抓包工具的证书,即绕过 SSL Pinning。
常见实现方式一句话
| 方式 | 在干啥 | 常见绕过方式 |
|---|---|---|
| OkHttp CertificatePinner | 绑定域名和证书哈希,check() 校验 | Hook CertificatePinner.check |
| X509TrustManager | checkServerTrusted() 校验证书链 | Hook checkServerTrusted |
| SSLSocketFactory | 创建/校验 SSL 套接字 | Hook createSocket 等 |
| Native 层 | so 里调 SSL_get_verify_result 等 | Hook SSL_get_verify_result 返回 0 |
记一句:先 jadx 搜 CertificatePinner、checkServerTrusted,再 Hook 对应方法让校验不抛异常/不拒绝。
二、找应用的 SSL Pinning 代码一般怎么干?
在干啥:反编译后搜关键字,定位校验逻辑
用 jadx 反编译 APK,搜 CertificatePinner 、checkServerTrusted 、certificatePinner 、TrustManager 、SSL 等,看是 OkHttp、HttpsURLConnection 还是自定义校验。
一般怎么干
bash
jadx -d output/ app.apk
grep -r "CertificatePinner" output/
grep -r "checkServerTrusted" output/
找到类名和方法后,写 Frida/Xposed 脚本 Hook 对应方法,让校验直接 return、不抛异常。
三、用 Frida 绕过 SSL Pinning 一般怎么干?
在干啥:Hook 证书校验方法,让校验「通过」
常见 Hook 点:OkHttp3.CertificatePinner.check 、X509TrustManager.checkServerTrusted 、SSLSocketFactory 相关方法。
Hook OkHttp CertificatePinner
js
Java.perform(function() {
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function(hostname, peerCertificates) {
console.log("[*] Bypassing SSL Pinning for: " + hostname);
return;
};
});
Hook checkServerTrusted(TrustManager)
js
Java.perform(function() {
var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
var SSLContext = Java.use("javax.net.ssl.SSLContext");
// 实际应用可能用自定义 TrustManager,需在 jadx 里找具体类名
// 这里示例 Hook 常见实现
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl"); // 仅示例,类名以实际为准
TrustManagerImpl.verifyChain.implementation = function() {
console.log("[*] Bypassing checkServerTrusted");
return arguments[0]; // 返回证书链,避免抛异常
};
});
(若应用用系统 X509TrustManager 接口,可枚举实现类再 Hook;或使用现成的 Frida 脚本如 frida-multiple-unpinning。)
Hook Native 层 SSL 校验(示例)
若校验在 so 里(如 libcrypto.so 的 SSL_get_verify_result),可 Hook 该函数让返回值恒为 0(表示验证通过):
js
Interceptor.attach(Module.findExportByName("libcrypto.so", "SSL_get_verify_result"), {
onLeave: function(retval) {
retval.replace(0);
}
});
注意:仅限授权环境;不得对他人应用做未授权抓包或传播脚本。
四、用 Burp 抓包的大致步骤(配合绕过)
在干啥:PC 开代理,设备连代理并装 Burp CA,应用流量经 Burp 才能看到;若应用有 Pinning,需先 Frida 绕过
- PC 上 Burp 监听 8080,记下 PC IP。
- 设备 WiFi 设置 HTTP 代理为 PC_IP:8080。
- 浏览器访问 http://burp 或 http://PC_IP:8080 下载 CA,安装到设备。
- 若应用仍报证书错误,说明有 SSL Pinning,用 Frida 注入上述脚本后再打开应用抓包。
注意:仅限授权、合规;不得对他人应用未授权抓包。
本节小结
你只要记住这几条就行:
- SSL Pinning = 应用只信任指定证书,不信任抓包 CA;绕过 = Hook 校验逻辑让校验「通过」。
- 先 jadx 搜 CertificatePinner 、checkServerTrusted ,确定实现方式;再 Frida Hook 对应方法(或 Native SSL_get_verify_result)。
- 绕过后配合 Burp 等设代理、装 CA,即可抓 HTTPS(仅限授权环境)。
- 仅限授权、合规环境下抓包与分析。
本节术语速查
| 术语 | 一句话解释 |
|---|---|
| SSL Pinning | 应用只信任指定证书/公钥,不信任系统 CA,防中间人。 |
| CertificatePinner | OkHttp 的证书钉扎 API,check() 校验域名与证书。 |
| checkServerTrusted | X509TrustManager 的方法,校验服务器证书链。 |
本节思考与练习
- 概念:装了 Burp 证书后应用仍报「证书错误」,可能是什么原因?怎么验证是 SSL Pinning?
- 应用 :若 jadx 里搜到 CertificatePinner ,你会 Hook 哪个类的哪个方法?若搜到的是 checkServerTrusted,又该 Hook 谁?
- 动手:在授权环境下,对一个带 SSL Pinning 的应用用 jadx 找到校验相关类和方法,写 Frida 脚本 Hook 后,用 Burp 抓到一个 HTTPS 请求。
- 动手 :若 Frida Hook Java 层后仍抓不到,考虑是否在 Native 层校验,用 strings 或 IDA 搜 SSL 、verify ,再尝试 Hook SSL_get_verify_result(仅限授权环境)。
下一节预告 :下一节讲Android 代码混淆与解混淆 ,会介绍 ProGuard/R8 混淆是啥、mapping.txt 怎么用、如何检测混淆和手动/自动解混淆。