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逆向安全合规接单指南
android·安全
消失的旧时光-19431 天前
Android 系统层扫盲 09:AMS、ATMS、WMS、PMS 到底分别管什么?
android·wms·pms·ams·aosp·atms
Godikov1 天前
Android 系统级设备应用踩坑实录:sharedUserId 签名、SDK 授权失败 -4、开机自启与 U 盘 OTA 升级
android
IT毕设实战小研1 天前
基于大数据的国内主要农作物产量趋势分析与可视化
android·java·大数据·django·课程设计
企业数字化笔记1 天前
固定资产历史数据怎么导入系统?Excel模板、字段映射和数据校验
android·java·数据库·后端
龙之叶1 天前
Android出海系列-GMS认证介绍
android
潮族大Z1 天前
Android性能优化:启动、内存、卡顿的一站式排查手册
android
事圆则缓1 天前
从suspend字节码到 Retrofit 协程桥:挂起函数识别与恢复
android·retrofit
杉氧1 天前
RN 性能调优指南:重渲染(Re-renders)控制与长列表(FlatList)优化
android·前端·react native
Coffeeee1 天前
claude-video 一个让你的Agent拥有看视频能力的Skill
android·人工智能·aigc