安卓App存在未知防护时如何成功实施MITM中间人攻击
安卓应用MITM抓包失败排查方案与非通用防护机制说明
高概率遗漏的MITM防护机制
- QUIC/HTTP3 协议优先策略:当前多数主流应用默认优先走UDP 443端口的QUIC协议,该协议的TLS握手实现在UDP层,常规HTTP代理默认不支持QUIC流量解密,要么直接放行UDP流量导致请求不经过代理的TLS解密逻辑,要么握手失败触发重连,表现就是完全看不到解密后的明文流量,和证书绑定失效的现象完全一致。
- Native层下沉的证书校验逻辑:市面通用SSL unpin脚本基本只覆盖Java层的OkHttp、系统默认SSLContext、WebView等上层组件的校验逻辑,大厂应用普遍会把核心接口的TLS校验逻辑下沉到内置的native so库中,自行实现公钥哈希比对、证书链校验,完全不调用系统Java层的证书校验接口,上层hook完全不生效。
- 自定义TLS栈实现:部分应用不会调用系统自带的OpenSSL/BoringSSL接口,而是自行编译内置独立的TLS实现,硬编码根证书公钥在so文件中,既不读取系统/用户证书存储,也不遵循
network-security-config配置规则,你提取到的配置文件仅对走系统网络API的非核心流量生效。 - 环境检测联动防护:通用反root/反检测脚本大多只覆盖基础的su路径检测、系统属性检测,多数主流应用还会检测Frida默认端口、frida-agent内存特征、ptrace调试附加状态、模拟器特征,检测到异常后不会直接闪退,而是静默切换到防护等级更高的自定义TLS栈,甚至直接返回加密的自定义协议流量,表现为无法解密SSL流量。
- 证书透明度(CT)强制校验:部分应用内置CT日志校验逻辑,即使代理证书被安装到系统信任区,只要证书不在公开CT日志列表、无法通过内置的CT公钥验证,就会直接断开连接,这类校验多数实现在native层,通用脚本不会覆盖。
- 多进程流量隔离:应用核心接口请求可能运行在独立的守护进程而非主进程中,若Frida仅附加主进程,独立进程内的证书校验逻辑不会被hook。
实战排查步骤
- 先确认流量协议:在测试机出口路由或代理端抓全量网卡包,查看目标应用的请求是TCP的TLS流量还是UDP的QUIC流量,如果存在大量UDP 443端口的目标流量,直接通过防火墙规则阻断测试机发往公网的UDP 443出站流量,强制应用回退到TCP层的HTTP/2协议,再尝试抓包。
- 确认Frida附加范围:启动应用后通过
frida-ps -U命令列出所有和目标应用包名关联的进程,将unpin脚本注入所有关联进程,不要仅附加UI主进程。 - 放弃依赖通用unpin脚本:直接hook底层通用TLS函数,不管上层是Java还是native实现,最终证书校验大多会调用OpenSSL层的
SSL_CTX_set_verify、X509_verify_cert等符号,直接hook这类函数强制返回校验通过,覆盖范围远高于上层通用脚本。 - 解决重打包问题:不需要纠结PC端apktool的版本兼容问题,在root后的实机上用MT管理器直接修改安装包内的
network-security-config文件,添加用户证书信任规则后重签名安装即可;也可以完全不用重打包,直接通过Frida hook系统NetworkSecurityConfigProvider相关逻辑,强制应用信任用户证书、忽略证书绑定规则。 - 隐藏Frida特征:不要用默认配置启动frida-server,修改默认监听端口、隐藏内存中的frida-agent特征、关闭SELinux提示,避免应用检测到Frida后触发静默防护;也可以采用重打包注入frida-gadget的方式,代替frida-server的附加模式,大幅降低被检测的概率。
- 对比模拟器与实机差异:模拟器环境下可以正常解密,说明应用在识别到模拟器环境时不会启用native层的高级防护逻辑,可以分别打印两个环境下应用加载的so库列表、TLS相关函数调用栈,定位实机环境下额外加载的防护模块,针对性绕过。
- 若遇到完全自定义的TLS栈,不需要死磕证书校验:直接hook libc层的
send/recv函数,在TLS解密完成、应用层处理明文数据的位置抓取明文即可。
注意:提取到的
network-security-config仅对调用系统标准网络API的请求生效,对native层自定义实现的TLS流量没有任何约束,不要被该配置误导判断。
你观测到的提取配置如下,规则本身确实声明生产环境信任系统证书,但该规则对自定义TLS栈无约束力:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates overridePins="true" src="system" /> </trust-anchors> </base-config> <debug-overrides> <trust-anchors> <certificates src="user" /> </trust-anchors> </debug-overrides> </network-security-config>
内容的提问来源于stack exchange,提问作者Flying Kitty
相关产品推荐
相关产品推荐

