【技术分享】如何在macOS上监控一个APP的HTTPS流量

https://p2.ssl.qhimg.com/t014cae6f5ae3465cc3.jpg

严正声明:本文仅限于技术讨论与学术学习研究之用,严禁用于其他用途(特别是非法用途,比如非授权攻击之类),否则自行承担后果,一切与作者和平台无关,如有发现不妥之处,请及时联系作者和平台

翻译:ForrestX386

预估稿费:130RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

 

0x00 前言

当你需要逆向分析一个网络协议的时候,或者进行一些关于网络安全方面的行为的时候,你就需要去收集网络中传输的流量数据,通过收集网络中的传输数据信息,你可以去理解网络协议是怎么工作的,或许还能发现网络中传输的敏感信息。

如果网络协议传输的是明文信息,那很好办,直接用tcpdump 或者wireshark等类似的抓包软件就可以获取网络协议传输的信息内容,但是现在越来越多的协议使用了加密机制,比如HTTPS协议,这时候就需要MITM(中间人攻击)进行拦截加密协议。

本篇文章我会向大家介绍如何在 OSX上监控一个app的HTTPS流量以及实验中遇到的问题。

0x01 正文

拦截HTTPS流量的基本步骤

1)生成一个根证书

2)安装这个根证书

3)用proxychains 去代理指定的app

4)使用mitmproxy 去拦截流量

一些需要安装的软件

1、 安装并配置proxychains

brew install proxychains-ng

创建一个名为 proxychains.conf 的文件,然后加入以下内容:

strict_chain
quiet_mode
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
http 127.0.0.1 8080

http 127.0.0.1 8080  这行最重要,它的意思是说重定向app所有的流量到127.0.0.1:8080 (mitmproxy默认监控端口就是8080),然后我们就可以用mitmproxy在127.0.0.1:8080 监控所有的流量了。

2、使用pip安装并配置mitmproxy

pip install --upgrade pip 
pip install mitmproxy

这两行命令就可以安装好mitmproxy

执行以下命令运行mitmproxy

./mitmproxy --host

接下来就是给系统安装根证书,默认情况下mitmproxy会自动生成一个根证书(mitm-ca-cert.pem),这个根证书位于~/.mitmproxy下面。

首先执行

open ~/.mitmproxy

然后,按下组合键 Command + Space ,然后输入Keychain Access, 回车

然后找到mitmproxy根证书,双击 ,或者将mitmproxy根证书拖拽到Keychain Access 窗口中上述执行OK,之后,你将会看到下图显示内容

http://p8.qhimg.com/t01d78a03607432780f.png

如果你足够细心的话,你会发现删除安装好的mitmproxy 根证书前面有个 红叉 ,这表示系统并不信任这个根证书, 为了让系统信任这个根证书,你需要这样做:右键单击mitmproxy根证书,然后选择"Get Info"(如果你是英文界面的话),展开 "Trust"将: When using this certificate 修改为 Always Trust修改后的内容如下:

http://p5.qhimg.com/t01edb53584ce03c9fa.png

接下来, 你还需要执行以下命令,这样系统才能完全信任这个根证书

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem

OK,最后的mitmproxy证书信息界面如下:

http://p1.qhimg.com/t01b45a31a51f3d88c1.png

看到了吧,mitmproxy 根证书前面的 红叉 提示不见了,说明系统完全信任了这个根证书

3、开始使用mitmproxy

其实github上mitmproxy的手册写的非常好,很详细,这里我就不过多解释了

现在我们已经做好了

1)配置proxychains 将app的http流量指向了127.0.0.1:8080

2)安装好了mitmproxy的根证书

3)mitmproxy运行OK

现在需要做的就是测试是否工作的OK

在另一个终端窗口执行:

proxychains4 -f proxychains.conf curl https://calebfenton.github.io/

现在切换到mitmproxy的运行窗口观察是否有流量被捕获到, 结果非常令人失望, 竟然没有捕获到任何流量,为毛?因为系统app 根本没鸟你,我查了一下proxychains 在github上的问题反馈列表,找到了原因 (和SIP有关): https://github.com/rofl0r/proxychains-ng/issues/78  你可以这样解决这个问题:

cp `which curl` .
proxychains4 -f proxychains.conf ./curl https://calebfenton.github.io/

或者你可以先安装一个wget,然后将curl替换为wget

brew install wget
proxychains4 -f proxychains.conf ./wget https://calebfenton.github.io/

注: wget不是系统app

一旦你观察到mitmproxy捕获到了通信数据,mitmproxy现在工作是正常的, 说明刚才新安装到系统的mitmproxy的根证书被系统信任了, proxychains 也正确地Hook了网络通信数据,看起来都很OK,可能很多人都很满足现在的一切了。

但是当我试图用proxychains Hook python 代码所产生的的网络数据的时候, 问题出现了。

python 代码如下(保存为文件req.py):

import requests
r = requests.get('https://calebfenton.github.io/')
print(r)

非常简单的一段代码(前提是你要安装了requests库),和上面curl起到的作用类似,但是执行proxychains4  python req.py 的时候出现了错误:

http://p0.qhimg.com/t01fd13b40cb7d63c8a.png

看到错误信息,我好像知道了问题的原因了,网络数据被Hook给了mitmproxy,mitmproxy给的证书requests根本不信任啊,因为python 代码根本不知道mitmproxy的根证书在哪儿啊,所以我们只要修改python代码,在get请求中指定mitmproxy的根证书路径即可

import requests
r = requests.get('https://calebfenton.github.io/', verify='/Users/caleb/.mitmproxy/mitmproxy-ca-cert.pem')
print(r)

使用verify参数指定mitmproxy根证书所在的路径

修改之后一切就Ok了,因为你告诉了requests去信任mitmproxy的证书。其实还有一个问题,如果你不能修改源代码,或者你用了不是requests库的其他模块呢?有个解决办法,对于requests库,如果你不能修改源码,设置一个环境变量REQUESTS_CA_BUNDLE指向/Users/caleb/.mitmproxy/mitmproxy-ca-cert.cer(mitmproxy根证书路径),然后在执行proxychains4

REQUESTS_CA_BUNDLE=/Users/caleb/.mitmproxy/mitmproxy-ca-cert.cer proxychains4 python req.py

举例栗子,以修改前的req.py为例(就是不加verify参数那个版本)

http://p6.qhimg.com/t013eff4dcd751f0b9f.png

如果是其他非requests库, 可以试着设置一个环境变量 SSL_CERT_FILE 指向/Users/caleb/.mitmproxy/mitmproxy-ca-cert.cer (mitmproxy根证书路径)

0x02. 总结

本篇文章介绍一些我在mitm https 通信试验中遇到的一些小问题,我使用proxychains,是因为我不想用iptables将所有的http流量都重定向到一个监听端口,我只想重定向一个app的流量到指定监听端口。 最后,希望你的试验也能顺利完成。

(完)