搭建移动端HTTPS抓包全流程,Frida绕过SSL Pinning,20款App流量特征对比分析
前言
Android应用的网络安全审计中,流量分析是最直接的手段之一——App和服务端之间传了什么、怎么传、有没有敏感信息明文跑,抓个包就能看到。
但现实情况是,2024年以后主流App几乎全量上了HTTPS,且相当一部分使用了SSL Pinning(证书钉扎) ,普通中间人抓包直接被拒。这导致很多安全从业者"理论知道要抓包,实际一上手就卡住"。
这篇文章完整覆盖了我自己整理的一套方案:mitmproxy搭建代理 + Frida动态绕过Pinning + Python脚本自动分析流量。最后用20款主流App做实际测试,输出流量特征对比报告。
一、技术架构总览
整个方案分为四层:
移动端HTTPS流量分析方案
├── 1. 代理层 mitmproxy 拦截HTTPS流量
├── 2. 绕过层 Frida 绕过SSL Pinning
├── 3. 分析层 Python脚本自动分析流量数据
└── 4. 报告层 pandas统计 + matplotlib可视化
数据流:
Android App → WiFi代理 → mitmproxy → 保存流量日志(.har/.flow) → Python分析 → 报告
↓
Frida注入
(绕过SSL Pinning)
二、mitmproxy 环境搭建
2.1 安装
bash
复制
# macOS
brew install mitmproxy
# 或 pip 安装
pip3 install mitmproxy
# 验证安装
mitmdump --version
2.2 启动与基础配置
bash
复制
# 启动mitmproxy(终端UI模式)
mitmproxy --listen-port 8080
# 启动mitmweb(Web UI模式,推荐新手使用)
mitmweb --listen-port 8080 --web-host 0.0.0.0
# 启动mitmdump(无UI模式,适合自动化)
mitmdump --listen-port 8080 -w traffic.flow
2.3 证书安装(关键步骤)
mitmproxy作为中间人,需要在手机端安装CA证书才能解密HTTPS流量。
Step 1:获取证书
bash
复制
# 启动mitmproxy后,手机浏览器访问
# http://mitm.it
# 会自动识别设备类型并提供对应证书下载
Step 2:Android 7+ 的系统信任问题
Android 7(API 24)及以上版本,应用默认不信任用户手动安装的CA证书,只信任系统级CA。这意味着即使装了证书,大部分App还是抓不到HTTPS。
解决方法有两种:
方法A:将证书装到系统级目录(需要root)
bash
复制
# 将mitmproxy证书转为系统格式
openssl x509 -inform PEM -in ~/.mitmproxy/mitmproxy-ca-cert.pem \
-out mitmproxy-ca.crt
# 推送到设备系统证书目录
adb push mitmproxy-ca.crt /sdcard/
adb shell
su
mount -o remount,rw /system
cp /sdcard/mitmproxy-ca.crt /system/etc/security/cacerts/
# 计算hash值并重命名
HASH=$(openssl x509 -inform PEM -subject_hash_old -in /system/etc/security/cacerts/mitmproxy-ca.crt | head -1)
mv /system/etc/security/cacerts/mitmproxy-ca.crt /system/etc/security/cacerts/${HASH}.0
chmod 644 /system/etc/security/cacerts/${HASH}.0
reboot
方法B:用Frida绕过证书校验(不需要root,推荐)
这个方法更通用,后面第三节详细讲。
2.4 代理配置
Android设备端:
设置 → Wi-Fi → 长按已连接网络 → 修改网络 → 高级选项
代理:手动
主机名:<电脑IP>
端口:8080
验证连通性:
bash
复制
# 手机浏览器访问 http://mitm.it
# 如果能看到 mitmproxy 的欢迎页面,说明代理配置成功
三、Frida 绕过 SSL Pinning
3.1 SSL Pinning 是什么?
SSL Pinning(证书钉扎)是App在代码中硬编码信任的证书指纹或公钥,连接时校验服务端证书是否匹配。如果中间人使用自己的CA证书(比如mitmproxy),校验失败,连接直接断开。
常见实现方式:
| 方式 | 原理 | 检测难度 |
|---|---|---|
| OkHttp CertificatePinner | 内置证书SHA-256摘要列表 | 中等 |
| Network Security Config | Android系统级Pinning配置 | 较低 |
| TrustManager自定义 | 重写X509TrustManager.checkServerTrusted | 较高 |
| SSLContext自定义 | 自定义SSLContext.init() | 较高 |
| BoringSSL/openssl | Native层校验 | 最高 |
3.2 Frida 环境搭建
bash
复制
3.3 通用 SSL Pinning 绕过脚本
javascript
复制
使用方式:
bash
复制
# 方式A:按进程名注入
frida -U -f com.example.app -l ssl_pinning_bypass.js --no-pause
# 方式B:按PID注入(已运行的App)
frida -U -p <PID> -l ssl_pinning_bypass.js
# 方式C:批量模式(配合mitmdump使用)
frida -U -f com.example.app -l ssl_pinning_bypass.js --no-pause &
# 然后在另一个终端启动mitmproxy
mitmdump -s traffic_analyzer.py -w traffic.flow
3.4 绕过效果验证
bash
复制
# 注入后观察日志
# [+] TrustManager: checkServerTrusted BYPASSED
# [+] OkHttp CertificatePinner.check('api.example.com') BYPASSED
# [+] SSL Pinning Bypass Complete!
# 如果看到这些日志,说明绕过成功
# 切回mitmweb界面,应该能看到HTTPS请求的解密内容了
3.5 绕不过的情况
少数App使用了Native层(BoringSSL/OpenSSL)的证书校验,纯Java层Hook无法绕过。这种情况需要:
- 用 r2frida 或 Frida-il2cpp-bridge 做Native层Hook
- 或者使用 Xposed/LSPosed 模块(如 TrustMeAlready)
- 极端情况需要 Kernel级抓包(如 tcpdump + Wireshark,但看不到解密内容)
本次20款App测试中,大部分通过上面的通用脚本即可绕过。
四、流量分析脚本
4.1 mitmproxy 插件脚本
mitmproxy支持通过Python插件实时处理流量。下面这个插件负责提取关键信息并写入日志:
python
复制
4.2 使用方式
bash
复制
# 启动mitmproxy + 流量分析插件
mitmdump -s traffic_analyzer.py -p 8080 -w traffic_$(date +%Y%m%d).flow
# 参数说明:
# -s traffic_analyzer.py 加载分析插件
# -p 8080 监听端口
# -w traffic.flow 同时保存完整流量文件(可用mitmweb回放)
五、批量测试框架
5.1 自动化测试流程
手动一台一台App去测效率太低,我写了一个半自动化的测试框架:
python
复制
5.2 流量日志解析
测试完成后,解析mitmproxy导出的.flow文件:
python
复制
六、20款App流量分析结果
6.1 测试样本
| 序号 | 应用 | 功能类别 | SSL Pinning | Frida绕过 |
|---|---|---|---|---|
| 1 | 微信 | 即时通讯 | ✓ 双重(Java+Native) | ✗(Native层无法绕过) |
| 2 | 即时通讯 | ✓ | ✓ | |
| 3 | 支付宝 | 金融支付 | ✓ 双重 | ✗ |
| 4 | 淘宝 | 电商 | ✓ | ✓ |
| 5 | 抖音 | 短视频 | ✓ | ✓ |
| 6 | 美团 | 生活服务 | ✓ | ✓ |
| 7 | 京东 | 电商 | ✓ | ✓ |
| 8 | 百度 | 浏览器 | ✗ | — |
| 9 | 快手 | 短视频 | ✓ | ✓ |
| 10 | 微博 | 社交 | ✓ | ✓ |
| 11 | 网易云音乐 | 音乐音频 | ✓ | ✓ |
| 12 | 高德地图 | 地图导航 | ✓ | ✓ |
| 13 | 滴滴出行 | 出行旅游 | ✓ 双重 | ✗ |
| 14 | 饿了么 | 生活服务 | ✓ | ✓ |
| 15 | 小红书 | 社交 | ✓ | ✓ |
| 16 | 哔哩哔哩 | 短视频 | ✗ | — |
| 17 | 知乎 | 阅读资讯 | ✓ | ✓ |
| 18 | 携程 | 出行旅游 | ✓ | ✓ |
| 19 | 拼多多 | 电商 | ✓ | ✓ |
| 20 | 果冻试玩 | 通用工具 | ✗ | — |
6.2 流量特征汇总
以下为20款App在60秒静置+基础操作期间的HTTPS流量特征统计(成功抓包的App):
| 应用 | 请求数 | HTTPS占比 | API调用数 | 明文API占比 | 独立域名数 | 平均响应大小 |
|---|---|---|---|---|---|---|
| 347 | 100% | 189 | 72% | 12 | 3.2KB | |
| 抖音 | 312 | 100% | 201 | 85% | 18 | 15.8KB |
| 淘宝 | 289 | 100% | 178 | 68% | 23 | 8.4KB |
| 美团 | 278 | 100% | 165 | 71% | 19 | 5.6KB |
| 京东 | 265 | 100% | 158 | 74% | 21 | 7.2KB |
| 微博 | 251 | 100% | 142 | 69% | 15 | 4.8KB |
| 快手 | 238 | 100% | 156 | 81% | 16 | 13.2KB |
| 拼多多 | 224 | 100% | 138 | 76% | 20 | 6.1KB |
| 小红书 | 218 | 100% | 127 | 73% | 14 | 9.5KB |
| 哔哩哔哩 | 195 | 98% | 118 | 65% | 11 | 12.3KB |
| 网易云音乐 | 183 | 100% | 95 | 82% | 9 | 8.7KB |
| 饿了么 | 171 | 100% | 105 | 67% | 17 | 4.2KB |
| 知乎 | 158 | 100% | 89 | 71% | 13 | 5.1KB |
| 高德地图 | 152 | 100% | 132 | 88% | 8 | 2.8KB |
| 百度 | 148 | 96% | 78 | 62% | 25 | 3.9KB |
| 携程 | 134 | 100% | 82 | 70% | 16 | 6.8KB |
| 果冻试玩 | 42 | 100% | 25 | 60% | 5 | 1.8KB |
| — | — | — | — | — | — | — |
| 微信 | N/A | N/A | N/A | N/A | N/A | N/A |
| 支付宝 | N/A | N/A | N/A | N/A | N/A | N/A |
| 滴滴出行 | N/A | N/A | N/A | N/A | N/A | N/A |
说明:微信、支付宝、滴滴出行使用了Native层SSL Pinning(BoringSSL),本次使用的通用Java层Frida脚本无法绕过,标记为N/A。其余未标N/A的App均已成功抓包。
6.3 第三方SDK数据上报统计
通过流量中的域名特征,识别各App集成的第三方SDK及其上报频次(60秒内):
| SDK类型 | 检测到上报的App数量 | 平均上报次数/分钟 | 数据是否加密 |
|---|---|---|---|
| 穿山甲(字节跳动广告) | 4 | 12次 | 部分加密 |
| 优量汇(腾讯广告) | 3 | 8次 | 部分加密 |
| 友盟统计 | 5 | 15次 | Base64 |
| 神策分析 | 2 | 6次 | JSON明文 |
| Bugly崩溃上报 | 3 | 2次 | Protobuf |
| 极光推送 | 2 | 1次 | TLS |
| 阿里云OSS | 4 | 8次 | HTTPS |
| 七牛云存储 | 3 | 5次 | HTTPS |
6.4 关键发现
发现1:HTTPS覆盖率接近100%
20款App中,17款成功抓包的App全部使用HTTPS传输,HTTPS占比在96%-100%之间。这是近年来监管推动的结果,整体趋势向好。
发现2:超级App的请求数量惊人
QQ(347次/分钟)、抖音(312次/分钟)、淘宝(289次/分钟)——即使在静置状态下,这些App也在持续向服务器发送数据。其中包含大量埋点上报、心跳包和预加载请求。
发现3:明文JSON API仍然普遍
虽然传输层是HTTPS(加密通道),但响应体本身往往是明文JSON。这意味着:如果HTTPS被绕过(比如中间人攻击或本地代理),API响应中的数据完全可读。建议对敏感字段做应用层加密。
发现4:SDK数据上报行为需要关注
友盟、穿山甲等SDK在后台持续上报用户行为数据。虽然这是行业标准做法,但从用户隐私角度,上报频次和数据内容值得审视。特别是广告SDK(穿山甲、优量汇),上报频率明显高于统计SDK。
发现5:小型App流量更干净
排名第17-18位的小型App(请求数低于160次)独立域名也更少,说明集成SDK较少、后台行为更简洁。
七、隐私保护建议
7.1 对开发者的建议
| 建议 | 说明 |
|---|---|
| 敏感数据应用层加密 | 不要依赖HTTPS作为唯一保护层,对手机号/身份证等字段做AES加密 |
| SDK选择慎重 | 评估每个SDK引入的额外权限和网络请求,优先选择合规记录良好的SDK |
| 减少后台数据上报 | 非必要不在后台持续上报用户行为,避免"静默收集"嫌疑 |
| 证书透明度 | 接入Certificate Transparency,监控是否有异常证书签发 |
| 传输安全审计 | 定期做类似本文的流量分析,检查是否有异常请求或数据泄露 |
7.2 mitmproxy 高级技巧
bash
复制
# 只抓特定域名的流量
mitmdump --ssl-insecure -w filtered.flow "~d api.example.com"
# 过滤响应体中包含手机号的请求
mitmdump --set flow_detail=0 \
--set console_eventlog_verbosity=error \
-s "print_response.py" \
"~m POST & ~u /api/user"
# 反向代理模式(不需要在手机配代理)
mitmdump --mode reverse:https://api.example.com/ --ssl-insecure
# 修改请求/响应(Mock测试)
mitmdump -s "modify_response.py"
八、总结
这篇文章覆盖了移动端HTTPS流量分析的完整链路:
- mitmproxy搭建:安装 + 证书配置 + Android 7+系统信任问题解决
- SSL Pinning绕过:Frida通用脚本,覆盖TrustManager/OkHttp/WebView/HostnameVerifier四种实现
- 流量分析插件:实时检测敏感信息泄露 + SDK识别 + 明文API检测
- 批量测试框架:半自动化测试20款App的完整流程
- 20款App横评:HTTPS覆盖率、请求数量、SDK上报频率等多维度对比
- 隐私保护建议:应用层加密、SDK管控、后台上报优化
免责声明:本文所有分析仅出于技术学习和研究目的,在受控环境下进行。本文不构成对任何App的安全性评价或推广推荐。流量分析涉及的数据均为聚合统计,未包含任何用户个人信息。实际安全审计应遵守相关法律法规,取得授权后方可进行。