1. 理解SSL Pinning与双向TLS验证的本质
当我们需要对移动应用或Web应用进行安全测试、调试或逆向分析时,抓包是最基础也最重要的手段之一。但现代应用普遍采用SSL Pinning(证书固定)和双向TLS验证(mTLS)这两种安全机制,使得传统的抓包工具如Fiddler、Charles或Wireshark直接失效。要突破这些限制,首先需要理解它们的工作原理。
SSL Pinning的核心思想是客户端预先存储服务端证书或公钥的指纹(通常是SHA-256哈希),在建立TLS连接时,将服务器返回的证书与本地存储的指纹比对,如果不匹配则终止连接。这有效防止了中间人攻击(MITM),因为即使攻击者拥有合法的CA签发证书也无法通过验证。
双向TLS验证则更为严格,不仅服务器需要向客户端证明身份(通过证书),客户端也需要向服务器证明自己的身份(通过客户端证书)。这种机制常见于银行、支付类应用,以及企业内部系统。客户端证书通常被内置在应用或设备中,没有证书就无法完成握手。
提示:SSL Pinning有多种实现方式,包括证书固定(Certificate Pinning)、公钥固定(Public Key Pinning)以及HPKP(HTTP公钥固定,已弃用)。目前移动端最常用的是公钥固定。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 传统抓包工具为何失效
使用Fiddler或Charles抓HTTPS流量的标准流程是:
- 在设备上安装抓包工具的根证书
- 配置代理指向抓包工具
- 工具作为中间人,分别与客户端和服务端建立TLS连接
- 解密并记录流量
但在SSL Pinning和双向TLS验证的场景下,这个流程会失败:
-
SSL Pinning导致连接中断:客户端检测到服务器证书指纹与预期不符(因为抓包工具使用了自签名证书),直接拒绝连接。你会看到类似"SSL handshake failed"或"Certificate verification failed"的错误。
-
双向TLS验证无法完成:抓包工具无法提供有效的客户端证书,服务器会拒绝连接。典型错误包括"403 Forbidden"或"TLS handshake failed"。
-
证书透明度(CT)检查:部分应用还会检查证书是否出现在公共CT日志中,进一步阻止自签名证书的使用。
3. 绕过SSL Pinning的技术方案
3.1 静态修改法(适用于Android/iOS应用)
对于移动应用,最直接的方法是修改应用本身,移除SSL Pinning逻辑。这需要一定的逆向工程能力:
Android应用:
- 使用apktool解包APK:
bash复制
apktool d target.apk -o output_dir - 分析smali代码或DEX文件,定位证书验证逻辑(常见于OkHttp、Retrofit等网络库)
- 修改验证逻辑或直接替换证书指纹
- 重新打包并签名:
bash复制apktool b output_dir -o modified.apk keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore debug.keystore modified.apk androiddebugkey
iOS应用:
- 使用CrackerXI或frida-ios-dump砸壳获取可调试的IPA
- 使用Hopper或IDA分析二进制文件
- 定位
SecPolicyCreateSSL、SecTrustEvaluate等安全API调用 - 使用theos编写tweak修改验证逻辑
- 重新签名并安装
注意:静态修改法需要处理代码混淆、完整性校验等防护措施,且每次应用更新都需要重新分析。
3.2 动态Hook法(无需修改应用)
使用运行时注入工具动态拦截和修改SSL验证函数:
Frida脚本示例(Android/iOS):
javascript复制Java.perform(function() {
var Certificate = Java.use("java.security.cert.Certificate");
Certificate.verify.implementation = function() {
console.log("Bypassing certificate verification");
return;
};
var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
X509TrustManager.checkServerTrusted.implementation = function() {
console.log("Bypassing server trust check");
return [Certificate.$new()];
};
});
运行脚本:
bash复制frida -U -f com.target.app -l bypass_ssl.js
Objection工具(基于Frida):
bash复制objection explore -s "android sslpinning disable"
3.3 使用特殊抓包工具
部分工具内置了SSL Pinning绕过功能:
- Burp Suite:配合Burp's CA证书和
burp-certifier扩展 - Charles Proxy:启用"SSL Proxying"并配置忽略证书错误
- HTTP Toolkit:自动处理Android/iOS的证书固定
配置示例(Burp Suite):
- 安装PortSwigger CA证书到设备
- 在Burp中启用"Invisible Proxy"模式
- 配置
User options -> TLS -> Pass Through添加目标域名
4. 突破双向TLS验证的限制
双向TLS验证的突破更为复杂,因为需要获取有效的客户端证书。以下是几种可行方案:
4.1 提取内置客户端证书
如果应用内置了客户端证书(如.p12或.bks文件),可以尝试提取:
Android密钥库提取:
bash复制adb pull /data/data/com.target.app/shared_prefs
# 查找包含"keystore"、"cert"等关键词的文件
使用KeyStore Explorer打开.bks文件(密码可能需要逆向分析)
4.2 中间人证书注入
对于使用系统证书库的应用,可以尝试:
- 将抓包工具的CA证书安装到系统受信任证书存储
- 使用工具生成客户端证书并注入到请求中
使用mitmproxy的clientcert插件:
python复制from mitmproxy import ctx
def load(loader):
loader.add_option(
"client_cert", str, "", "Path to client certificate"
)
def tls_clienthello(data):
if data.client.sni == "target.domain":
data.ignore_connection = True
data.establish_tls_with_client_cert(ctx.options.client_cert)
4.3 模拟合法设备
对于企业/银行类应用,可能需要:
- 获取合法设备的完整配置(包括证书、设备ID等)
- 使用Android模拟器或越狱iOS设备复现环境
- 通过动态分析提取完整的TLS上下文
5. 实战案例:抓包某金融类App
以某银行App为例(同时使用SSL Pinning和双向TLS验证):
-
环境准备:
- 已root的Android设备
- Frida服务器运行中
- Burp Suite配置好代理
-
绕过SSL Pinning:
bash复制objection -g com.bank.app explore -s "android sslpinning disable" -
提取客户端证书:
bash复制adb pull /data/data/com.bank.app/files/cert.p12 openssl pkcs12 -in cert.p12 -out client.pem -nodes -
配置Burp使用客户端证书:
- User options -> TLS -> Client SSL Certificates
- 添加目标域名并选择client.pem
-
流量解密:
- 确认Burp能看到完整的HTTPS请求/响应
- 对于加密的请求体,可能需要额外的解密脚本
6. 高级技巧与注意事项
6.1 对抗证书绑定升级
部分应用会实施动态证书绑定:
- 首次启动从服务器获取证书指纹
- 定期更新绑定策略
- 使用代码混淆保护验证逻辑
应对方案:
- 使用Frida拦截网络请求,修改服务器响应
- 定位内存中的证书指纹并动态替换
- 完全禁用网络库的证书验证功能
6.2 处理HPKP等高级机制
虽然HPKP(HTTP Public Key Pinning)已被弃用,但仍有应用使用:
- 通过HTTP响应头
Public-Key-Pins指定 - 浏览器会强制执行,但移动端较少使用
解决方案:
- 修改HTTP响应头(需中间人位置)
- 使用
--ignore-hpkp启动Chromium
6.3 法律与道德边界
重要提醒:
- 仅对你有权测试的应用进行操作
- 企业环境需获得书面授权
- 金融类应用可能涉及法律风险
- 尊重用户隐私和数据保护法规
7. 工具链推荐
根据不同场景选择合适的工具组合:
| 场景 | 推荐工具 | 备注 |
|---|---|---|
| Android SSL Pinning | Frida + Objection | 动态Hook最佳选择 |
| iOS SSL Pinning | SSL Kill Switch 2 | 需越狱设备 |
| 双向TLS企业应用 | mitmproxy + 客户端证书 | 高级配置灵活 |
| 浏览器HPKP | Chrome开发者工具 | 禁用安全策略 |
| 大规模自动化 | Appium + 自定义Hook | 适合QA测试 |
对于持续对抗的安全测试,建议建立自动化框架:
- 自动检测SSL Pinning类型
- 根据策略选择绕过方案
- 验证抓包结果完整性
- 生成测试报告
我在实际工作中发现,约60%的应用使用标准的网络库实现SSL Pinning(如OkHttp的CertificatePinner),这些可以通过通用Hook方案解决。剩下的40%需要定制化分析,其中约10%会采用硬件级安全方案(如TEE),这时可能需要物理设备调试或放弃抓包方案。
