mitmdump Android 抓包

1. 环境准备

1.1 Ubuntu 主机

安装基础工具:

bash 复制代码
sudo apt update
sudo apt install -y mitmproxy adb tcpdump tshark sqlite3 openssl

确认工具可用:

bash 复制代码
mitmdump --version
adb version
tshark --version
openssl version

mitmproxy 安装包提供:

  • mitmproxy:交互式 UI
  • mitmdump:命令行 / 脚本化抓包
  • mitmweb:Web UI

1.2 Android 真机

前置条件:

  • 已开启 USB 调试,adb devices 能看到设备。
  • 需要修改系统 CA 或配置网络转发时,设备必须有 root。
  • 抓自身应用流量时,先确认目标应用 UID:
bash 复制代码
adb shell dumpsys package <package_name> | grep -E 'uid=|appId=' | head

示例:

bash 复制代码
adb shell dumpsys package com.android.vending | grep -E 'uid=|appId=' | head

2. 启动 mitmdump

2.1 普通代理模式

适合应用遵循系统代理的场景:

bash 复制代码
mitmdump --listen-host 127.0.0.1 --listen-port 18080 \
  --set block_global=false \
  -w /tmp/capture.flows

2.2 反向代理模式

适合不使用系统代理、只观察指定域名的场景:

bash 复制代码
mitmdump --mode reverse:https://example.com \
  --listen-host 127.0.0.1 --listen-port 18080 \
  --set block_global=false \
  -w /tmp/capture.flows

2.3 保持前台运行

后台 nohup 进程可能被会话清理。调试链路时建议保持前台运行:

bash 复制代码
mitmdump --mode reverse:https://example.com \
  --listen-host 127.0.0.1 --listen-port 18080 \
  --set block_global=false \
  -w /tmp/capture.flows

3. 手机流量导入电脑

3.1 adb reverse

主机和手机不在同一网段时,使用 adb reverse 最简单:

bash 复制代码
adb reverse tcp:18080 tcp:18080

手机访问 127.0.0.1:18080 时,流量会转发到电脑的 127.0.0.1:18080

验证:

bash 复制代码
adb shell curl -k -sS -o /dev/null \
  -w '%{http_code} %{remote_ip}\n' \
  https://127.0.0.1:18080/

清理:

bash 复制代码
adb reverse --remove tcp:18080

3.2 系统代理

适合普通应用:

bash 复制代码
adb shell settings put global http_proxy <host>:18080

清理:

bash 复制代码
adb shell settings put global http_proxy :0

注意:系统代理影响整机流量,且部分系统应用或 native 网络库可能不走代理。

3.3 iptables 转发

适合不遵循代理的应用。以下示例只拦截指定 UID 和目标 IP:

bash 复制代码
adb shell su 0 sh -c '
iptables -t nat -A OUTPUT \
  -m owner --uid-owner <uid> \
  -p tcp -d <target_ip> --dport 443 \
  -j REDIRECT --to-ports 18080
'

查看规则:

bash 复制代码
adb shell su 0 sh -c 'iptables -t nat -L OUTPUT -v -n --line-numbers'

删除规则:

bash 复制代码
adb shell su 0 sh -c '
iptables -t nat -D OUTPUT \
  -m owner --uid-owner <uid> \
  -p tcp -d <target_ip> --dport 443 \
  -j REDIRECT --to-ports 18080
'

如果应用使用 QUIC,可临时拒绝该 UID 的 UDP/443,使其回退 TCP:

bash 复制代码
adb shell su 0 sh -c '
iptables -I OUTPUT 1 \
  -m owner --uid-owner <uid> \
  -p udp --dport 443 \
  -j REJECT
'

清理:

bash 复制代码
adb shell su 0 sh -c '
iptables -D OUTPUT \
  -m owner --uid-owner <uid> \
  -p udp --dport 443 \
  -j REJECT
'

注意:DNAT --to-destination 127.0.0.1:18080 在部分设备上受 route_localnet 限制;REDIRECT --to-ports 更可用。

4. 替换系统 CA

4.1 生成 mitmproxy CA

首次运行 mitmdump 后,CA 会生成在 ~/.mitmproxy/

bash 复制代码
mitmdump --listen-host 127.0.0.1 --listen-port 18080

确认 CA:

bash 复制代码
openssl x509 -in ~/.mitmproxy/mitmproxy-ca-cert.pem \
  -noout -subject -issuer -dates

计算 Android 证书文件名:

bash 复制代码
openssl x509 -in ~/.mitmproxy/mitmproxy-ca-cert.pem \
  -noout -subject_hash_old

假设输出为 c8750f0d,推送到设备:

bash 复制代码
adb push ~/.mitmproxy/mitmproxy-ca-cert.pem /data/local/tmp/c8750f0d.0

4.2 临时 bind mount 系统 CA 目录

Android 15 的 /system/etc/security/cacerts 只读。可复制一份到 /data/local/tmp,加入 mitmproxy CA 后临时 bind mount:

bash 复制代码
adb shell su 0 sh -c '
rm -rf /data/local/tmp/cacerts-mitm
mkdir -p /data/local/tmp/cacerts-mitm
cp /system/etc/security/cacerts/* /data/local/tmp/cacerts-mitm/
cp /data/local/tmp/c8750f0d.0 /data/local/tmp/cacerts-mitm/
chown root:root /data/local/tmp/cacerts-mitm/*
chmod 644 /data/local/tmp/cacerts-mitm/*
chcon u:object_r:system_security_cacerts_file:s0 \
  /data/local/tmp/cacerts-mitm/*
chcon u:object_r:system_security_cacerts_file:s0 \
  /data/local/tmp/cacerts-mitm
mount --bind /data/local/tmp/cacerts-mitm \
  /system/etc/security/cacerts
'

验证:

bash 复制代码
adb shell su 0 sh -c '
ls -lZ /system/etc/security/cacerts/c8750f0d.0
'

4.3 卸载临时 CA

bash 复制代码
adb shell su 0 sh -c '
umount /system/etc/security/cacerts
ls /system/etc/security/cacerts/c8750f0d.0 2>&1
'

ls 返回 No such file or directory 表示已恢复原系统 CA 目录。

注意两个坑:

  • cp /system/etc/security/cacerts/. 会报 Cross-device link不会复制任何证书 ,必须用通配符 cp /system/etc/security/cacerts/*
  • 除了证书文件,挂载目录本身的 SELinux 上下文也必须改成 system_security_cacerts_file ;只改文件不改目录,应用会读不到信任库(ls -ldZ /system/etc/security/cacerts 挂载后应为 system_security_cacerts_file)。

4.4 证书校验失败

部分系统应用(如 Finsky)会额外校验证书链或使用自己的网络栈。即使系统 CA 目录已包含 mitmproxy CA,仍可能出现:

text 复制代码
Client TLS handshake failed. The client does not trust the proxy's certificate
(OpenSSL Error([('SSL routines', '', 'sslv3 alert certificate unknown')]))

此时流量已到达 mitmdump,但 TLS 握手失败,无法观察 HTTP 层内容。

5. 导出抓包文件到电脑

mitmdump -w 写入的是 mitmproxy flow 文件,通常直接保存在电脑上:

bash 复制代码
mitmdump --mode reverse:https://example.com \
  --listen-host 127.0.0.1 --listen-port 18080 \
  --set block_global=false \
  -w /tmp/capture.flows

如果文件在手机上,例如 tcpdump pcap:

bash 复制代码
adb pull /data/local/tmp/capture.pcap /tmp/capture.pcap

6. 在电脑上分析流量

6.1 mitmdump 查看 flow

bash 复制代码
mitmdump -nr /tmp/capture.flows

增加详情:

bash 复制代码
mitmdump -nr /tmp/capture.flows --set flow_detail=2

只看指定 host:

bash 复制代码
mitmdump -nr /tmp/capture.flows \
  --set flow_detail=1 \
  --view-filter 'host == "example.com"'

导出为文本:

bash 复制代码
mitmdump -nr /tmp/capture.flows \
  --set flow_detail=3 > /tmp/capture.txt

6.2 mitmproxy 交互式分析

bash 复制代码
mitmproxy -r /tmp/capture.flows

常用快捷键:

  • Enter:进入 flow 详情
  • q:返回 / 退出
  • Tab:切换请求 / 响应
  • f:编辑过滤表达式

6.3 tshark 分析 pcap

查看 DNS 和 TLS SNI:

bash 复制代码
tshark -r /tmp/capture.pcap \
  -Y 'dns.qry.name || tls.handshake.extensions_server_name' \
  -T fields \
  -e dns.qry.name \
  -e tls.handshake.extensions_server_name

去重:

bash 复制代码
tshark -r /tmp/capture.pcap \
  -Y 'dns.qry.name || tls.handshake.extensions_server_name' \
  -T fields \
  -e dns.qry.name \
  -e tls.handshake.extensions_server_name \
  | sed 's/[[:space:]]*$//' | sort -u

查看 HTTP:

bash 复制代码
tshark -r /tmp/capture.pcap \
  -Y 'http' \
  -T fields \
  -e frame.time \
  -e ip.src \
  -e ip.dst \
  -e http.request.method \
  -e http.host \
  -e http.request.uri \
  -e http.response.code \
  -e http.location

6.4 常用排查点

  • 确认 mitmdump 正在监听:
bash 复制代码
ss -ltnp | grep 18080
  • 确认 adb reverse:
bash 复制代码
adb reverse --list
  • 确认 iptables 规则计数是否增长:
bash 复制代码
adb shell su 0 sh -c \
  'iptables -t nat -L OUTPUT -v -n --line-numbers'
  • 查看目标应用实时连接:
bash 复制代码
adb shell su 0 sh -c 'ss -tnp | grep <package_or_uid>'

7. 清理现场

bash 复制代码
adb reverse --remove tcp:18080

adb shell su 0 sh -c '
iptables -t nat -D OUTPUT \
  -m owner --uid-owner <uid> \
  -p tcp -d <target_ip> --dport 443 \
  -j REDIRECT --to-ports 18080

iptables -D OUTPUT \
  -m owner --uid-owner <uid> \
  -p udp --dport 443 \
  -j REJECT

umount /system/etc/security/cacerts
'

adb shell settings put global http_proxy :0

最终确认:

bash 复制代码
adb reverse --list
adb shell su 0 sh -c 'iptables -t nat -S OUTPUT'
adb shell su 0 sh -c 'iptables -S OUTPUT | head'
adb shell su 0 sh -c \
  'ls /system/etc/security/cacerts/c8750f0d.0 2>&1'
adb shell settings get global http_proxy
相关推荐
心平气和量大福大1 小时前
android-实例2-数据库sqlite(查询)
android·数据库·sqlite
时代分流1 小时前
云手机推荐2026:安卓全能、批量挂机、原生iOS全覆盖
android·ios·智能手机
恋猫de小郭1 小时前
Gradle 9.7.0 将提速 Android 构建,Sync 提升接近一倍
android·前端·flutter
Dovis(誓平步青云)2 小时前
心情日记的安全编辑流程:输入校验、删除确认与状态回收
android·运维·服务器·开发语言·windows·安全
宋拾壹2 小时前
php对接携程验票核销
android·php·android studio
weixin_4038101311 小时前
AI智能体写安卓自动化脚本教程:Cursor/Trae+CLI 实战,自然语言生成代码
android·人工智能·自动化·跨境电商·安卓自动化脚本·多账户运营
呆呆小孩13 小时前
零基础学 MySQL(上):从建库建表到增删改查,一篇搭好 SQL 基础
android·sql·mysql
catchadmin13 小时前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
android·ios·ai·php
FfHUCisI14 小时前
Golang 数据库连接池深度调优
android·数据库·golang