严正声明:本文仅限于技术讨论与学术学习研究之用,严禁用于其他用途(特别是非法用途,比如非授权攻击之类),否则自行承担后果,一切与作者和平台无关,如有发现不妥之处,请及时联系作者和平台
翻译: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,之后,你将会看到下图显示内容
如果你足够细心的话,你会发现删除安装好的mitmproxy 根证书前面有个 红叉 ,这表示系统并不信任这个根证书, 为了让系统信任这个根证书,你需要这样做:右键单击mitmproxy根证书,然后选择"Get Info"(如果你是英文界面的话),展开 "Trust"将: When using this certificate 修改为 Always Trust修改后的内容如下:
接下来, 你还需要执行以下命令,这样系统才能完全信任这个根证书
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem
OK,最后的mitmproxy证书信息界面如下:
看到了吧,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 的时候出现了错误:
看到错误信息,我好像知道了问题的原因了,网络数据被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参数那个版本)
如果是其他非requests库, 可以试着设置一个环境变量 SSL_CERT_FILE 指向/Users/caleb/.mitmproxy/mitmproxy-ca-cert.cer (mitmproxy根证书路径)
0x02. 总结
本篇文章介绍一些我在mitm https 通信试验中遇到的一些小问题,我使用proxychains,是因为我不想用iptables将所有的http流量都重定向到一个监听端口,我只想重定向一个app的流量到指定监听端口。 最后,希望你的试验也能顺利完成。