在移动应用开发、接口调试、安全测试与逆向分析领域,抓包是一项必备的核心技能。随着 Android 系统安全机制的不断收紧,从 Android 7.0 的证书信任分离,到 Android 14 的系统证书目录迁移,再到普遍应用的 SSL 证书锁定与双向认证,普通的代理抓包早已不再 "开箱即用"。
本文将系统性梳理 Android 平台抓包的完整技术路径,从最基础的证书安装,到系统级证书植入,再到证书锁定绕过与双向认证突破,逐层深入,覆盖绝大多数实战场景。
一、抓包基本原理与工具选型
1.1 HTTPS 中间人攻击原理
所有 HTTP/HTTPS 抓包工具的核心逻辑都是中间人攻击(MITM):抓包工具在客户端与服务端之间充当代理,客户端与代理建立 TLS 连接,代理再与真实服务器建立 TLS 连接,从而实现流量的解密、查看与篡改。
要让客户端接受代理的证书,必须在设备上安装抓包工具的根证书(CA Certificate)并使其被信任。信任层级的不同,直接决定了能抓取哪些 App 的流量。
1.2 主流抓包工具对比
表格
| 工具 | 类型 | 平台 | 优势 | 适用场景 |
|---|---|---|---|---|
| Charles | 商业 GUI | Win/Mac/Linux | 界面友好、功能完善、移动端配置简单 | 日常开发调试、接口分析 |
| mitmproxy | 开源 CLI/GUI | 全平台 | Python 脚本扩展、可编程、HTTP/2 支持好 | 自动化抓包、批量处理、爬虫逆向 |
| Fiddler | 商业 GUI | Win 为主 | Windows 生态深度集成、FiddlerScript 强大 | Windows 平台深度调试 |
| Burp Suite | 安全专业工具 | 全平台 | 渗透测试套件齐全、改包重放能力强 | 安全测试、漏洞挖掘 |
| HttpCanary | 移动端 APP | Android | 手机端直接抓包、无需电脑 | 快速现场排查、VPN 模式绕过代理检测 |
选型建议:日常开发调试首选 Charles;自动化与脚本化场景选 mitmproxy;安全渗透测试用 Burp Suite。
二、基础抓包:用户证书安装与代理配置
这是最基础的抓包方式,适用于 targetSdkVersion < 24 的老旧应用,或开发者自己调试的 App。
2.1 导出抓包工具根证书
以 Charles 为例:
- 打开 Charles,进入
Help → SSL Proxying → Save Charles Root Certificate - 保存为
.pem或.cer格式文件 - 将证书文件传输到手机存储
mitmproxy 首次启动后,证书自动生成在~/.mitmproxy/目录下,文件名为mitmproxy-ca-cert.cer。
2.2 Android 用户证书安装
- 进入手机设置 → 安全 → 加密与凭据 → 从存储设备安装
- 选择刚才传输的证书文件
- 输入证书名称(如 "Charles"),凭据用途选择VPN 和应用
- 确认安装,安装后可在信任的凭据 → 用户中查看
注意:Android 安装用户证书必须设置锁屏密码(PIN / 图案 / 指纹),且删除所有用户证书前无法取消锁屏密码。
2.3 WiFi 代理配置
- 确保手机与电脑处于同一局域网
- 查看电脑局域网 IP(Windows:
ipconfig,Mac/Linux:ifconfig) - 手机长按已连接 WiFi → 修改网络 → 代理设置为手动
- 代理主机名填写电脑 IP,端口填写抓包工具监听端口(Charles 默认 8888,mitmproxy 默认 8080)
- 保存后,电脑端抓包工具会弹出连接确认,点击 Allow 即可
完成以上步骤后,浏览器和部分老旧 App 的 HTTPS 流量应该已经可以正常抓取。但你很快会发现:绝大多数现代 App 抓不到 HTTPS 包,显示 CONNECT 或证书错误。
这就引出了 Android 7.0+ 的核心限制。
三、进阶:Android 7.0+ 系统证书安装
3.1 为什么用户证书不够用了
Android 7.0(API 24)引入了 ** 网络安全配置(Network Security Config)** 机制,默认行为发生了根本性变化:
- targetSdkVersion ≥ 24 的应用,默认只信任系统 CA 证书,不再信任用户安装的证书
- 只有开发者在
network_security_config.xml中显式声明<certificates src="user" />,才会信任用户证书
这意味着,你安装的用户证书对市面上绝大多数 App 都是无效的。要突破这个限制,有两条路:
- 把证书安装到系统证书目录(需要 Root)
- 反编译修改 App 的网络安全配置(需要重打包)
3.2 用户证书 vs 系统证书核心差异
表格
| 特性 | 用户证书 | 系统证书 |
|---|---|---|
| 存储路径 | /data/misc/user/0/cacerts-added/ | /system/etc/security/cacerts/Android 14+:/apex/com.android.conscrypt/cacerts |
| 信任级别 | 用户级,应用可选择忽略 | 系统级,所有应用默认信任 |
| 修改权限 | 普通用户即可安装 | 需要 Root + 系统分区挂载读写 |
| 锁屏要求 | 必须设置锁屏密码 | 无强制要求 |
3.3 Root 设备安装系统证书
前置条件:设备已获取 Root 权限(Magisk 推荐),电脑安装 ADB 与 OpenSSL。
步骤一:证书格式转换与重命名
系统证书有严格的命名规则:文件名是证书 subject DN 的 MD5 哈希值(旧格式),后缀为.0。
bash
运行
# 1. 如果是 der 格式(.cer/.der),先转 pem openssl x509 -inform DER -in charles.cer -out charles.pem # 2. 计算 subject 哈希(旧版格式) openssl x509 -inform PEM -subject_hash_old -in charles.pem | head -1 # 输出类似:7bf17d07 # 3. 重命名证书文件 mv charles.pem 7bf17d07.0步骤二:推送到设备并移入系统目录
bash
运行
# 推送到临时目录 adb push 7bf17d07.0 /data/local/tmp/ # 进入设备并获取 Root adb shell su # Android 13 及以下:挂载 system 分区为可写 mount -o remount,rw /system # Android 14+:挂载 apex 分区 mount -o remount,rw /apex/com.android.conscrypt # 移动证书到系统目录 # Android 13-: cp /data/local/tmp/7bf17d07.0 /system/etc/security/cacerts/ # Android 14+: cp /data/local/tmp/7bf17d07.0 /apex/com.android.conscrypt/cacerts/ # 设置正确权限 chmod 644 /system/etc/security/cacerts/7bf17d07.0 # 重启设备 reboot重启后,在设置 → 安全 → 信任的凭据 → 系统中能看到你的抓包证书,即安装成功。此时绝大多数未做证书锁定的 App 都可以正常抓包。
3.4 非 Root 方案:VirtualApp / 多开框架
如果设备无法 Root,可以使用 VirtualApp、太极、VMOS 等虚拟引擎,在虚拟环境中运行目标 App,配合 JustTrustMe 等模块在进程内 Hook 绕过证书校验。这种方式无需修改系统,但兼容性有限,加固 App 可能无法运行。
四、证书锁定(SSL Pinning)绕过
安装系统证书后,仍有大量 App 无法抓包,表现为连接失败、证书校验错误或直接无网络。这通常是因为 App 开启了SSL Pinning(证书锁定 / 证书钉扎)。
4.1 什么是 SSL Pinning
普通 HTTPS 只验证证书由受信任的 CA 签发,而证书锁定更进一步:App 内置了服务器证书的公钥哈希或证书本身,TLS 握手时会比对服务器返回的证书与内置值是否一致。
即使你的抓包证书是系统信任的 CA,只要公钥对不上,App 就会直接断开连接。这是专门对抗中间人攻击的安全机制。
4.2 常见绕过方案
方案一:LSPosed + TrustMeAlready / JustTrustMe
这是最通用、成功率最高的方案。
- 设备安装 Magisk + LSPosed 框架
- 安装TrustMeAlready或JustTrustMe Plus模块
- 在模块作用域中勾选目标 App
- 强制停止目标 App 后重新打开
原理:通过 Hook 系统 SSL 库中创建 TrustManager、校验证书链的关键方法,绕过所有证书校验逻辑,让任何证书都能通过验证。
提示:JustTrustMe 偏向老版本系统,TrustMeAlready 和 SSLUnpinning 对新版本 Android 和 OkHttp 框架支持更好,建议多模块组合尝试。
方案二:Frida 脚本动态 Hook
对于快速调试,Frida 比安装 Xposed 模块更灵活。
javascript
运行
// SSL Pinning bypass 通用脚本片段 console.log("[*] Starting SSL unpinning..."); // Hook SSLContext.init 方法 Java.perform(function() { var SSLContext = Java.use("javax.net.ssl.SSLContext"); SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "Ljava.security.SecureRandom;").implementation = function(kms, tms, sr) { console.log("[+] SSLContext.init called, bypassing pinning"); // 传入空的 TrustManager,不做任何校验 var trustAllCerts = Java.registerClass({ name: "com.example.TrustAll", implements: ["javax.net.ssl.X509TrustManager"], methods: { checkClientTrusted: function(chain, authType) {}, checkServerTrusted: function(chain, authType) {}, getAcceptedIssuers: function() { return []; } } }); var tm = Java.array("javax.net.ssl.TrustManager", [trustAllCerts.$new()]); this.init(kms, tm, sr); }; });执行命令:
bash
运行
frida -U -f com.target.app -l unpin.js --no-pause方案三:反编译移除锁定逻辑
如果上述 Hook 方案失效(如 App 使用自研 SSL 库或原生层加密),则需要反编译 APK,定位证书锁定代码并注释掉,重打包后安装。这需要较强的逆向分析能力。
五、双向认证(mTLS)抓包突破
绕过了证书锁定后,你可能还会遇到更硬核的防护:双向 TLS 认证(Mutual TLS /mTLS)。这是金融、政务、高安全级 App 的标配。
5.1 双向认证原理
普通 HTTPS 是单向认证:只有客户端验证服务器身份。双向认证则要求服务器也验证客户端身份—— 客户端必须在 TLS 握手阶段出示自己的客户端证书,服务器验证通过后才建立连接。
客户端证书通常以.p12/.pfx(PKCS#12 格式)或.bks格式内置在 App 安装包中,并受密码保护。没有正确的客户端证书和私钥,你的抓包代理即使能解密流量,也无法通过服务器的身份校验。
5.2 如何识别双向认证
抓包时出现以下特征,基本可以判定为双向认证:
- Charles / Burp 显示
SSL handshake failed或no suitable certificate found - Burp Suite 事件日志出现
server requires client certificate相关提示 - 直接用浏览器访问接口 URL,提示需要选择客户端证书
5.3 从 APK 中提取客户端证书
步骤一:搜索证书文件
bash
运行
# 解压 APK unzip target.apk -d target_extracted # 搜索 PKCS12 证书文件 find target_extracted -name "*.p12" -o -name "*.pfx" -o -name "*.bks"证书常存放于assets/、res/raw/目录,也可能被加密藏在 so 库或 dex 中。
步骤二:尝试破解证书密码
如果找到.p12文件但不知道密码:
- 尝试空密码、常见弱密码(
123456、password、包名等) - 使用
openssl pkcs12 -in client.p12 -info测试 - 逆向分析 App 代码,查找加载证书时传入的密码参数
步骤三:导出证书与私钥
bash
运行
# 从 p12 中提取客户端证书 openssl pkcs12 -in client.p12 -clcerts -nokeys -out client.crt # 提取私钥 openssl pkcs12 -in client.p12 -nocerts -out client.key5.4 抓包工具配置客户端证书
Charles 配置:
Proxy → SSL Proxying Settings → Client Certificates- 添加目标域名,导入
.p12证书文件并输入密码 - 保存后重新抓包
Burp Suite 配置:
Settings → Network → TLS → Client TLS certificates- 勾选
Override user options,点击 Add - 指定目标主机,导入 PKCS#12 文件并输入密码
配置完成后,代理在与服务器握手时会自动出示客户端证书,从而通过服务端身份验证。
5.5 进阶:Hook 提取证书与密钥
当证书被加密存储或动态生成,静态提取失败时,可以使用 Frida Hook KeyStore 或 SSLContext,在运行时导出客户端证书和私钥。r0capture 等开源工具已封装好相关能力,可直接 Dump 出 SSL 层的明文流量,无需手动处理证书。
六、特殊场景与高级技巧
6.1 代理检测绕过
部分 App 会检测系统是否设置了 HTTP 代理,发现代理后直接拒绝联网。绕过方式:
- VPN 模式抓包:使用 HttpCanary、Postern 等工具,通过 VPN 服务接管流量,不设置系统代理
- 透明代理:路由器层面配置透明代理或 iptables 转发,设备端无感知
- adb reverse 反向代理:适合 USB 连接场景,
adb reverse tcp:8080 tcp:8080,手机端代理设为127.0.0.1:8080
6.2 模拟器抓包优势
强烈建议使用 Android 模拟器(雷电、夜神、Genymotion、Android Studio Emulator)进行抓包分析:
- 自带 Root 权限,安装系统证书方便
- 可随时快照回滚,不怕搞坏环境
- 支持多种 Android 版本,便于兼容性测试
- 配合 Wireshark 可直接抓取虚拟机网卡的底层流量
6.3 非 HTTP 协议抓包
HTTP/HTTPS 只是应用层协议,如果 App 使用 TCP、UDP、WebSocket、gRPC 等协议:
- WebSocket:Charles、mitmproxy 均原生支持
- TCP/UDP 原始流量:使用 Wireshark 抓网卡层数据包
- 自定义二进制协议:配合 Frida Hook 加解密函数,在内存中 Dump 明文
七、常见问题排查清单
表格
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 完全抓不到任何包 | 代理不通 / 不在同一网段 | 检查 IP 端口、防火墙、同一 WiFi |
| HTTP 正常,HTTPS 全是 CONNECT | 证书未安装或未信任 | 检查证书是否正确安装到系统 |
| 浏览器正常,App 无网络 | App targetSdk ≥ 24 + 用户证书 | 安装系统证书或绕过 Pinning |
| 部分接口正常,特定接口失败 | 该接口开启了 SSL Pinning | 使用 JustTrustMe / Frida 绕过 |
| 所有接口 SSL 握手失败 | 双向认证,缺少客户端证书 | 提取客户端证书并配置到抓包工具 |
| 系统证书安装后不显示 | 命名格式错误 / 权限不对 | 检查哈希值、文件名、文件权限 |
八、写在最后
Android 抓包本质上是一场安全机制与调试需求的博弈。从用户证书到系统证书,从单向锁定到双向认证,防护手段在升级,绕过方法也在演进。没有万能方案,往往需要多种技术组合使用。
合规提示:本文所述技术仅用于合法的开发调试、安全测试与学习研究用途。未经授权对他人应用进行抓包、篡改数据、逆向分析,可能违反《网络安全法》及相关法律法规,请务必在授权范围内开展工作。
掌握抓包能力只是第一步,真正的价值在于通过流量分析理解业务逻辑、定位接口问题、发现安全隐患。希望这份指南能帮你建立完整的知识体系,在实战中少走弯路。