转载自:http://mrpeak.cn/blog/mitmproxy/
现阶段给iOS设备进行网络抓包的手段非常之多,除了我之前介绍的tcpdump,wireshark之外,还有Charles,以及和Charles同样好用的mitmproxy,其实还有更多,比如更小众的debookee。似乎知道Charles的同学更多一些,但其实Charles有的功能mitmproxy基本都有,mitmproxy还免费,而且对于terminal用户来说使用起来更亲近。
如何使用mitmproxy?
安装mitmproxy
我们可以通过brew或者pip来安装mitmproxy,没有安装brew的同学可以先通过如下命令安装brew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
完成之后,执行如下命令安装mitmproxy
使用mitmproxy抓包
第一步,首先启动mitmproxy,在terminal输入:
第二步,再在iPhone上设置http代理:
IP地址填你Mac系统当前的IP,端口默认8080。
可以通过在terminal输入ifconfig en0获取Mac的IP地址:
第三步,第一次使用mitmproxy的时候需要在iPhone上安装CA证书,这一步和Charles一样都需要做,原因后面解释。打开iPhone Safari,输入地址:mitm.it,在下图中点击Apple安装证书。
第三步只需要做一次。
观察mitmproxy流量
接下来我们就可以使用mitmproxy查看所有通过iPhone端的http请求了,包括https请求,如何破解https流量的后面也会分析。
mitmproxy初看起来可能不如Charles直观,其实稍微把玩下就用起来很顺了,mitmproxy是基于terminal交互的,主要分为两个界面:请求列表界面和请求详情界面。
请求列表界面
请求详情界面
大部分时候我们都是在这两个界面之间切换,切换方式也非常简单。可以在列表界面,用鼠标点击某个请求进入详情界面,但mitmproxy美妙之处在于可以用快捷键来完成界面的切换和功能的使用,而且快捷键与vim保持一致。
所以我们可以:
- 在列表界面,按用j,k或者上下方向键在列表上浏览。
- 在列表界面,按回车进入详情界面。
- 在详情界面,按q,返回列表界面。
- 在详情界面,按tab键或者h,l,在Request,Response,Detail三个tab之间切换。按j,k或者上下方向键可以滚动查看详情。
- 在列表界面,按G跳到最新一个请求。
- 在列表界面,按g跳到第一个请求。
- 在列表界面,按d删除当前选中的请求,按D恢复刚才删除的请求。
上面上面的几个快捷键就基本可以完成绝大部分的HTTP请求分析。
拦截http请求
mitmproxy也可以拦截请求,操作起来也很方便。
我们现在列表界面输入i,进入Intercept Filter模式。按esc可以退出intercept filter模式。
在intercept filter模式输入我们想要的filter就可以开始拦截了,比如我输入baidu\.com,按回车,所有域名中带baidu.com的请求就被拦截了,被拦截的请求会用橙色标记出来:
请求拦截会后可以编辑后再发送,也可以直接放行,按a就直接放行了。
编辑请求再发送
在上面拦截请求之后,我们可以编辑之后再发送。首先当选中被拦截的请求按回车进入详情页面,在详情页面按tab键可以在三个tab(Request,response,detail)之间切换,按e之后进入详情编辑模式:
按e进入编辑模式之后,我们要进一步选择编辑的request部分,如下图箭头所示选中一个按对应的字母就可以了:
之后就可以使用方向键或者h,j,,k,l,选中自己想要编辑的字段,回车之后就可以输入新内容,按esc退出当前编辑,按a可以再新建一个field,按d可以删除当前field,按esc退回上一个界面,下图为Request Header的edit界面:
看着快捷键挺多,其实和vim非常相似,把玩个几分钟之后就可以熟练使用了,比Charles的图形界面点击起来要快捷很多。
mitmproxy还有很多其他的功能,感兴趣的可以去官网https://mitmproxy.org查看。
用一句话总结mitmproxy:既免费又好用。
为何要安装CA证书?
同Charles一样,mitmproxy也需要在iPhone设备上安装CA证书。
这是因为mitmproxy要拦截解析https请求的话,要实施中间人攻击。正常情况下中间人攻击无法通过客户端的证书校验,mitmproxy的做法是临时实时的生成自己的证书,但这临时的证书要被客户端信任,就只能在iPhone设备上安装一个被信任的CA来签发临时的证书。也就是说,你信任了安装的mitmproxy的证书,也就信任了mitmproxy作为CA所签发的所有证书。
但是,这是一个非常危险的行为。
安装信任第三方CA证书是个危险的行为,无论是Charles还是mitmproxy,信任之后,第三方就可以无条件实施中间人攻击了,你手机上很多App自以为安全的https连接通道都不再安全了,你的Safari通过https浏览的网页内容也可能被窃听了。
所以,建议调试完之后在手机上删除第三方CA证书。
无论是Charles,还是mitmproxy,在调试完之后记得在【设置】-【通用】-【描述文件】中删除证书。
mitmproxy是如何实施中间人攻击的?
知其然还要知其所以然,学会用工具之后还要明白工具背后的原理,mitmproxy是如何实施中间人攻击的呢?
证书校验中一个重要环节是hostname验证。
获取正确的hostname
mitmproxy作为https代理,捕捉到手机端的请求之后,会发送一个同样的请求到server,并和server展开安全握手获取server的Certificate,再从Certificate中获取Common Name和Subject Alternative Name。签一个和Common Name,Subject Alternative Name一致的证书就可以骗过客户端了。所以即使客户端请求是使用的IP地址,这种方式也是行得通的。
如何防止中间人攻击?
iOS预防上述的中间人攻击也很简单,在客户端App做ssl pinning就可以了。
ssl pining分为certificate pinning和public key pinning两种,目前主流的第三方HTTP framework(AFNetworking和Alamofire)都支持ssl pinning功能。
做了证书或者公钥绑定之后,Charles和mitmproxy的https流量都无法正常获取了。
另外我个人建议不光要做ssl pinning,任何经过https发送的内容App要再自己做一层加密,没有绝对的安全,保不准哪天https流量就被人破解了。
之前Path偷偷上传用户通讯录的丑闻就是因为,Path既没有做ssl pinning,也没有对上传的内容做加密,最后就只有程序员背锅了,这种事情产品经理又怎么会了解呢。