0、前言
停更了一段时间,期间主要在忙项目。现在整理一下做过的案例,既能复盘,也能分享。本文记录一次某证券 App 抓包绕过的完整分析过程,重点讲思路,不光是结果。
一、检测判断:先分清断在哪一层
1. VPN 检测
使用小黄鸟(HttpCanary)进行判断:开启小黄鸟之后,App 变得更"糟糕",一直提示"尝试重连"。
但其他功能(比如开户预约)不受影响,唯独登录不行 → 可以判断存在 VPN 检测。
后续分析发现,会一直重连是因为交易组件会持续发起接口请求,并且这里存在 VPN 检测。笔者最终没有绕 VPN 这条路,后续对交易功能的抓包均基于 Hook 完成,这里不过多展开。
2. 代理检测
直接使用 Wi-Fi 代理:发现重连消失,其他功能也能正常使用 → 可以判断没有做 Wi-Fi 代理检测。本以为美滋滋,可一登录,却来了一勺冷水:通讯失败。

既然 Wi-Fi 代理没问题,那就是证书检测了。
3. 证书检测(本次分析重点)
单向证书绕过 —— 本次案例要学习和分析的重点
可以直接使用现成工具:
https://github.com/Fuzion24/JustTrustMehttps://github.com/ViRb3/TrustMeAlready/releaseshttps://pan.baidu.com/s/1wgqkzP0guy5TFwZka0k__Q?pwd=73pa(本次案例中可以成功绕过)双向证书绕过(mTLS) —— 服务端还会校验客户端证书,需要进行源码分析,本次不涉及
国密证书绕过 —— 难度太大,一般遇到只能求助大佬,或直接使用 Hook 抓包,本次不涉及
二、分析证书检测:从异常栈到源码
可能有师傅会疑惑:明明有工具可以直接利用,为什么还要费劲分析源码?
统一解释一下:作为安全从业者,既要有使用工具的能力,也要有独立开发适配脚本的能力,否则永远只是"脚本小子"。
目前掌握的信息:一登录就提示
通讯失败,说明点击登录就会触发证书检测。这种问题优先看 Android 日志。点击登录后查看日志,第一行就能看到
SSLHandshakeException(TLS 握手异常)——标准的证书校验失败特征。
继续分析日志,搜索
Caused by,在栈底找到了 App 自己的方法——PbHttpUtils.checkSSLCertificate()抛出的异常。这里说明一下,为什么选择搜索
Caused by:报错信息就像俄罗斯套娃——最外面一层告诉你
通讯失败,其实里面还裹着一层证书校验不过,再里面还有一层更细的原因。Caused by就是每一层套娃上贴的标签,写着我是被里面那一层带出来的。顺着标签一层层往里拆,拆到最里面那个,才是真正出事的地方。为什么会选择分析最后一个?
套娃拆到最后那个,是第一个出事的。App 自己的校验代码往往就是第一个出事的——它先发现证书不对、先拒绝,然后系统库一路把这个
坏消息往外传,越传越像通讯失败。所以看最里面那层,最容易撞见 App 自己的代码。为什么要优先看 App 自己的方法:
第三方库的方法太多,分析不过来,而且逆向拿到的源码里也不一定有第三方库的源码。做 App 逆向,分析对象必然是这个 App 自己做了什么——所以优先从 App 自己的类入手。

知道是谁抛的异常,就去源码里搜索
checkSSLCertificate,找到了如下源码。可惜由于编译问题,核心代码无法查看,只能看到方法签名。
虽然看不到方法体,但可以做推理:
点击登录,就触发异常,那么登录时必然进行了证书校验; 校验不通过,就必然抛出异常; 因此可以断定: checkSSLCertificate就是证书校验方法。绕过思路随之而来:既然它会做证书校验,那我不让它执行,不就等于没校验?没校验,不就可以正常抓包了?
三、Hook 代码编写与运行
把
checkSSLCertificate方法hook出来,但是不执行这个访问Java.perform(function () {var PbHttpUtils = Java.use("xxx.xxx.httputils.PbHttpUtils") PbHttpUtils.checkSSLCertificate.implementation = function () {console.log("hook证书") }});正常运行即可
成功抓到登录数据包。

夜雨聆风