监控虚拟机中的 HTTPS 流量
1 背景
前几天对某服务的电脑版客户端产生了兴趣,想要分析一下它的 HTTPS 流量。
如果在真机上安装程序,截获流量还要用另一台主机开热点,实属麻烦,因此选择了用虚拟机来搞。
整个环境的搭建并不复杂,不过还是遇到了一点儿小坑,在此做个记录。
2 环境
- 主机系统:Linux Manjaro v21.0.2
- 虚拟机软件:VirtualBox v6.1.18
- 虚拟系统:Windows 7 Pro
- 目标软件:115 电脑版 Windows 端 v24.1.0.10
- 神器:mitmproxy v6.0.2
3 设置过程
3.1 虚拟机
要截获虚拟系统的流量,就要让所有流量都过主机系统,因此虚拟机的网络应设置为 Host-only
,
首先打开 VirtualBox 的 “Host Network Manager”(从”File” 菜单中打开,或者直接使用热键 Ctrl+H
),新建一个适配器(Adapter) ,一切使用默认配置即可。
注意:无需启用 “DHCP Server” ,因为有坑,稍候会说明坑在哪里。
修改虚拟机的 Network 设置,适配器类型选择 Host-only Adapter
,并选择刚创建的适配器,一般是 vboxnet0
。
3.2 主机
3.2.1 IP 转发
这里的网络结构,跟将主机作为热点的情况几乎完全一致,只不过用前面创建的 Host-only
适配器取代了作为热点的 WiFi 适配器。因此要做的事情也与配置热点网络类似。
开启 IP 转发:
1 | sudo sysctl -w net.ipv4.ip_forward=1 |
添加 iptables
规则,包装出站报文:
1 | sudo iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE |
命令中的
wlp3s0
是上网用的网络设备名称,请根据实际情况替换。
这两步设置完成后,虚拟机内系统就可以正常上网了。
3.2.2 端口转发
由于目标是截获虚拟机的 HTTPS 流量,这里依然借助神器 mitmproxy。
以透明代理模式启动 mitmproxy:
1 | mitmproxy --mode transparent --listen-port 9999 --showhost |
这里使用
9999
作为透明代理的端口。
将来自虚拟机的,发往 80 和 443 端口的 TCP 数据包,都转发到透明代理端口。
1 | sudo iptables -t nat -A PREROUTING -i vboxnet0 \ |
如果系统中开启了防火墙,需要开放对透明代理端口的入站连接,这里以 ufw
为例:
1 | sudo ufw allow 9999/tcp |
3.3 虚拟系统
3.3.1 设置 IP
由于前面没有开启 DHCP 服务器,在虚拟系统内需要手工设置 IP 。
前面创建的适配器, IP 地址是 192.168.56.1
,子网掩码(Network Mask)是 255.255.255.0
。因此虚拟系统的 IP 应使用 192.168.56.[X]
(X
取值 [2,255]),并将网关(Gateway)设置为 192.168.56.1
。
3.3.2 导入 CA 证书
在虚拟系统内打开浏览器,访问 http://mitm.it
,如果设置一切正常,将看到如下画面:
点击 Windows 下面的 “Get mitmproxy-ca-cert.p12”,导入 mitmproxy 的 CA 证书。导入过程一切使用默认配置即可。
3.4 效果
在 mitmproxy 界面按 z
,清空之前截获的内容。之后回到虚拟系统内,启动目标程序,一切小动作尽收眼底:
4 填坑
最后说一下设置过程中遇到的坑。
一开始创建适配器时,我选择了启用 DHCP 服务。并在虚拟系统的网络设置上,直接使用 DHCP 服务分配的 IP ,结果怎么也上不去网。
最后发现,问题出在适配器的 DHCP 服务并不会下发网关地址,因此虚拟系统中的网络设备,只设置了 IP 地址和子网掩码,并未设置网关,从而导致虚拟系统无法上网。
那么网关到底是个什么东西?为什么它这么重要呢?
网关是一个子网的大门,当子网内的设备需要向一个子网外的 IP 发送数据包时,该数据包会发往网关,由网关转发给子网外的 IP。而来自子网外的回应报文,也会由网关转发给子网内的对应设备。(摘自:维基百科)