25、Android证书绑定绕过实战案例:银行应用绕过、支付应用绕过、社交应用绕过
各位同学,今天我们来聊点真刀真枪的东西。前面讲了那么多证书绑定的原理和检测方法,说白了都是为了这一刻——实战绕过。
我个人习惯把证书绑定绕过分为三类:客户端Hook绕过、框架级绕过、以及底层替换绕过。每种手法对应不同的应用场景。今天我就拿银行、支付、社交这三类典型应用,带大家走一遍完整的绕过流程。
核心观点:没有绝对安全的绑定方案。只要攻击者能控制客户端运行环境,绑定就能被绕过。区别只在于成本高低。
25.1 银行应用绕过:SSL Pinning + 混淆 + 反调试
银行应用是证书绑定的重度用户。我遇到过某国有银行的手机银行,用了三层绑定:OkHttp的CertificatePinner、WebView的onReceivedSslError、以及原生层的TrustManager重写。
嗯,这里要注意。银行应用通常还加了反调试和代码混淆。你直接上Frida可能会被检测到。我的做法是:
- 先过反调试:用Frida的
setTimeout延迟注入,或者用DobbyHook掉检测函数 - 定位绑定点:搜索关键词"checkServerTrusted"、"CertificatePinner"、"SSL"
- Hook关键方法:直接返回
void或true
来看一个实际案例。某银行App的绑定代码长这样:
// 银行App中的证书绑定逻辑(简化版)
TrustManager tm = new X509TrustManager() {
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// 检查证书公钥是否在白名单中
if (!isPinValid(chain[0])) {
throw new CertificateException("Pin mismatch!");
}
}
};
绕过方法很简单。用Frida Hook掉checkServerTrusted,让它什么都不做:
// Frida脚本:绕过银行App证书绑定
Java.perform(function() {
var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
TrustManager.checkServerTrusted.implementation = function(chain, authType) {
console.log('[+] Bypassed checkServerTrusted');
// 直接返回,不抛异常
};
});
我曾经在测试某银行App时,发现它除了Java层的绑定,还在Native层用openssl做了二次校验。那怎么办?用Frida Stalker跟踪SSL_CTX_set_verify函数,找到回调地址后直接NOP掉。
小技巧:银行App通常会在onReceivedSslError里proceed()之前做额外校验。你可以Hook这个回调,直接调用handler.proceed()。
25.2 支付应用绕过:支付宝/微信的Native层绑定
支付应用比银行应用更狠。它们通常把证书绑定逻辑放在Native层,用C++写的。你Hook Java层根本没用。
我记得有一次分析某支付App,发现它用了Chromium的net::TransportSecurityState来做绑定。这玩意儿是C++写的,Java层根本看不到。
绕过思路有两种:
- 方案A:Hook Native层的SSL函数——比如
SSL_connect、SSL_do_handshake,在握手完成后替换证书 - 方案B:用Frida的Interceptor Hook底层BoringSSL/OpenSSL——直接修改内存中的证书校验结果
来看一个实际可用的Frida脚本片段:
// 绕过支付App的Native层证书绑定
Interceptor.attach(Module.findExportByName("libcrypto.so", "X509_verify_cert"), {
onLeave: function(retval) {
console.log("[+] X509_verify_cert called, retval: " + retval);
// 强制返回1(成功)
retval.replace(1);
}
});
你想想看,为什么支付应用要这么折腾?说白了,支付场景对安全性要求极高。一旦被中间人攻击,用户的资金安全就出问题了。所以它们不惜牺牲性能,也要把绑定做到Native层。
警告:绕过支付应用的证书绑定,可能违反相关法律法规。本文仅用于安全研究和渗透测试教学,请勿用于非法用途。
25.3 社交应用绕过:WebView + 混合绑定
社交应用的情况比较特殊。它们通常既有原生页面,又有WebView加载的H5页面。证书绑定往往是混合模式——原生API用一套绑定,WebView用另一套。
我遇到过某社交App,它的聊天功能走的是WebSocket over HTTPS,而朋友圈功能走的是HTTP/2。两套绑定逻辑完全不同。
绕过社交应用的证书绑定,我建议分三步走:
- 先抓包确认:用
tcpdump或Wireshark看流量走向,确定哪些请求走了HTTPS - Hook WebView的SSL回调:
onReceivedSslError是必Hook的 - 处理WebSocket:WebSocket的证书校验通常走
SSLSocketFactory,需要单独Hook
来看一个WebView绑定的绕过示例:
// 绕过社交App的WebView证书绑定
Java.perform(function() {
var WebViewClient = Java.use('android.webkit.WebViewClient');
WebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
console.log('[+] WebView SSL error bypassed');
handler.proceed(); // 忽略证书错误
};
});
嗯,这里有个坑。有些社交App会在onReceivedSslError里检查error.getPrimaryError(),如果是SSL_UNTRUSTED就拒绝连接。你需要把handler.proceed()放在条件判断之前执行。
25.4 三种场景的绕过对比
我把这三种场景的绕过难度和手法整理成了表格,方便大家对比:
| 应用类型 | 绑定层级 | 绕过难度 | 推荐手法 | 典型坑点 |
|---|---|---|---|---|
| 银行应用 | Java + Native | ⭐⭐⭐⭐ | Frida Hook + Stalker | 反调试、Native二次校验 |
| 支付应用 | Native (C++) | ⭐⭐⭐⭐⭐ | Interceptor Hook底层SSL库 | BoringSSL/OpenSSL版本差异 |
| 社交应用 | Java + WebView | ⭐⭐⭐ | WebView回调Hook + SSLSocketFactory | WebSocket独立校验 |
25.5 绕过后的注意事项
绕过证书绑定只是第一步。你抓包拿到数据后,还要注意:
- 数据完整性校验:很多App会对请求体做签名,你改了数据就得重新签名
- 时间戳校验:请求里通常带时间戳,过期了会被拒绝
- 设备指纹:绕过绑定后,你的设备指纹可能被标记,导致账号被封
我曾经在测试某社交App时,绕过了证书绑定,抓到了聊天记录。但因为我用的模拟器,设备指纹被识别了,账号直接被封了24小时。所以,真机 + 真实SIM卡是绕过绑定的基本配置。
总结一下:证书绑定绕过没有银弹。银行应用重在反调试和Native校验,支付应用重在底层SSL库的Hook,社交应用重在WebView和WebSocket的混合处理。每种场景都要针对性地选择工具和手法。
好了,今天的实战案例就到这里。记住,绕过证书绑定只是安全研究的一小步。真正的挑战在于,如何在绕过之后,还能保持对应用行为的完整观察和分析。