Android App HTTPS 抓包与 SSL Pinning 绕过
本文将详细介绍如何搭建完整的 Android App HTTPS 抓包环境,并使用 Frida 动态注入技术绕过 SSL Pinning 证书校验机制。
1. 环境准备
| 组件 | 版本要求 | 用途 |
|---|---|---|
| Ubuntu / macOS / Windows | 任意 | 主机环境(安装 Frida、mitmproxy) |
| Android 模拟器 | API 34 | 运行目标 App |
| Frida | 17.x+ | 动态注入 / 绕过 SSL Pinning |
| mitmproxy | 最新版 | HTTP/HTTPS 抓包分析器 |
安装必要工具
pip install frida-tools mitmproxy
2. 下载并配置 Android 模拟器
2.1 安装 Android SDK Command-line Tools
解压并配置环境变量:
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator
2.2 下载系统镜像
使用 sdkmanager 下载 Android 34 (API Level 34) 的 x86_64 镜像:
sdkmanager "system-images;android-34;google_apis;x86_64"
注意:选择 google_apis 而非 google_apis_playstore,后者限制较多,不便于 root 和注入操作。
2.3 创建 AVD (Android Virtual Device)
avdmanager create avd -n Pixel_API_34 \
-k "system-images;android-34;google_apis;x86_64" \
--device "pixel"
2.4 启动模拟器(可写系统分区)
emulator -avd Pixel_API_34 \
-no-snapshot \
-gpu swiftshader_indirect \
-netdelay none \
-netspeed full \
-writable-system
参数说明:
-writable-system:允许修改 /system 分区,用于安装证书-no-snapshot:禁用快照,确保每次启动状态干净-gpu swiftshader_indirect:使用软件渲染,兼容性更好-netdelay none -netspeed full:移除网络延迟限制
3. 准备 frida-server
3.1 下载对应版本的 frida-server
前往 Frida Releases 下载与本机 frida-tools 版本一致的 frida-server-android-x86_64。
查看本机 Frida 版本:
frida --version
3.2 推送到模拟器
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server"
3.3 启动 frida-server
adb shell "/data/local/tmp/frida-server &"
验证运行状态:
adb shell "ps | grep frida"
4. 配置代理与 mitmproxy
4.1 启动 mitmproxy
在宿主机上启动代理服务:
mitmproxy --listen-host 0.0.0.0 --listen-port 8080
也可以使用 Web 界面版本:
mitmweb --listen-host 0.0.0.0 --listen-port 8080
4.2 配置模拟器系统代理
Android 模拟器访问宿主机使用特殊 IP 10.0.2.2:
adb shell settings put global http_proxy 10.0.2.2:8080
验证代理配置:
adb shell settings get global http_proxy
# 输出:10.0.2.2:8080
4.3 安装 CA 证书
在模拟器浏览器中访问:
http://mitm.it选择 “Android” 下载证书
安装证书到系统信任区(需要可写系统分区)
5. 准备 SSL Pinning 绕过脚本
创建 unpinning.js 文件,用于 Hook Java 层的证书校验逻辑:
// filepath: unpinning.js
// Frida script for bypassing SSL Pinning in Android apps
Java.perform(function () {
console.log('[+] Starting SSL Pinning Bypass...');
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
// Implement a new TrustManager to ignore cert errors
var TrustAll = Java.registerClass({
name: 'org.hello.TrustAll',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function (chain, authType) {
console.log('[+] checkClientTrusted bypassed');
},
checkServerTrusted: function (chain, authType) {
console.log('[+] checkServerTrusted bypassed');
},
getAcceptedIssuers: function () {
console.log('[+] getAcceptedIssuers bypassed');
return [];
}
}
});
// Replace the default TrustManager with ours
var initSSLContext = SSLContext.init.overload(
'[Ljavax.net.ssl.KeyManager;',
'[Ljavax.net.ssl.TrustManager;',
'java.security.SecureRandom'
);
initSSLContext.implementation = function (km, tm, sr) {
console.log('[+] Hooking SSLContext.init()');
console.log('[+] Bypassing SSL Pinning via TrustManager');
initSSLContext.call(this, km, [TrustAll.$new()], sr);
};
console.log('[+] SSL Pinning Bypass Ready!');
});
工作原理:
- Hook
SSLContext.init()方法 - 替换默认的
TrustManager为自定义实现 - 自定义 TrustManager 接受所有证书,不进行校验
6. Frida 注入与抓包
6.1 查找目标进程
启动目标 App 后,查找其进程信息:
frida-ps -Uai | grep com.example.app
6.2 注入脚本
方式一(通过 PID):
frida -U -p <PID> -l unpinning.js
方式二(通过包名,推荐):
frida -U -f com.example.app -l unpinning.js --no-pause
方式三(Attach 到运行中的进程):
frida -U -n com.example.app -l unpinning.js
6.3 观察输出
成功注入后会看到类似输出:
[+] Starting SSL Pinning Bypass...
[+] Hooking SSLContext.init()
[+] Bypassing SSL Pinning via TrustManager
[+] checkServerTrusted bypassed
[+] SSL Pinning Bypass Ready!

6.4 开始抓包
保持 mitmproxy 运行状态,在 App 中执行网络请求。此时可在 mitmproxy 界面中看到:
-> https://api.example.com/login 200 OK
POST /login
Content-Type: application/json
{"username": "test", "password": "123456"}
可以实时查看、修改、重放请求和响应内容。

7. 常用辅助命令
| 功能 | 命令 |
|---|---|
| 查看 frida-server 进程 | `adb shell ps |
| 检查代理端口监听 | sudo lsof -i :8080 或 `netstat -an |
| 测试代理连通性 | adb shell curl -I http://10.0.2.2:8080 |
| 清除系统代理设置 | adb shell settings put global http_proxy :0 |
| 列出所有 AVD | emulator -list-avds |
| 查看已连接设备 | adb devices |
| 重启 adb 服务 | adb kill-server && adb start-server |
| 查看 Frida 版本 | frida --version |
8. 整体流程架构
┌─────────────────────────────────────────────────────┐
│ Android App │
│ ↓ │
│ [Frida Hook 绕过 SSL 校验] │
└─────────────────────────────────────────────────────┘
↓
[系统代理] 10.0.2.2:8080
↓
┌─────────────────────────────────────────────────────┐
│ mitmproxy (宿主机) │
│ • 解密 HTTPS 流量 │
│ • 查看/修改请求响应 │
│ • 记录完整会话 │
└─────────────────────────────────────────────────────┘
↓
[真实的后端服务器]
9. 常见问题与解决方案
9.1 无法连接到 mitmproxy
问题:模拟器无法访问宿主机的 8080 端口
解决:
- 检查防火墙是否允许 8080 端口
- 确认使用
10.0.2.2而非localhost或127.0.0.1 - 验证 mitmproxy 监听在
0.0.0.0而非127.0.0.1
9.2 证书错误仍然存在
问题:即使注入了脚本,仍然提示证书错误
解决:
- 检查 CA 证书是否正确安装到系统信任区
- 某些 App 使用 Native 层校验,需要额外 Hook
- 尝试使用更全面的绕过脚本(如 frida-multiple-unpinning)
9.3 Frida 连接失败
问题:frida-ps -U 无法列出进程
解决:
- 确认 frida-server 版本与 frida-tools 版本一致
- 检查 frida-server 是否正在运行
- 尝试重启 adb 服务:
adb kill-server && adb start-server
10. 总结
通过本文的完整流程,我们实现了:
- 搭建 Android 模拟器环境:使用 Google APIs 镜像,启用可写系统分区
- 部署 Frida 框架:动态注入 JavaScript 代码到目标进程
- 配置中间人代理:通过 mitmproxy 拦截 HTTPS 流量
- 绕过 SSL Pinning:Hook 证书校验逻辑,接受自签名证书
- 分析加密流量:以明文形式查看所有网络请求
这套方案适用于大多数 Android App 的安全测试和逆向分析场景。对于采用更复杂保护机制的应用(如 Native 层校验、代码混淆、反调试等),需要结合更高级的技术手段。
免责声明:本文内容仅供学习研究使用,请勿用于非法用途。未经授权对他人应用进行抓包分析可能违反法律法规。