HTTPS Interception In Action

最近我喜欢上了玩iphone游戏,整天琢磨着怎么作弊。比如刷刷排行榜。于是我就先从抓包入手,看它给服务器发了些什么,哪些是我可以改的。

首先,我把我的windows7,做成了一个wifi热点。然后让iphone连上去。假设我iphone获得的IP是192.168.137.4,那么网关就是192.168.137.1。这个IP对应我pc上的一个虚拟网卡。用wireshark对这个interface进行抓包即可。很遗憾。这个游戏的所有网络通信全是HTTPS。我用wireshark抓到的全是加密后的数据,看不懂了。

于是man-in-the-middle proxy就上场了。HTTPS的身份认证大部分是单向的,client只检查server是否是真的,而server不检查client的身份。所以我们只需要把client欺骗过去就行了。client的检查方法很简单,看server的证书是否是通过一个证书链颁发,而最根上那个证书是一个可信赖的Certificate Authority(CA)。于是,我们只需要在client上植入一个假的CA证书即可。通常来说,只需要修改下系统设置,而不用更改App。

首先推荐的是来自微软的fiddler2。网上大多数文章讲到这里就停下来了,因为他们除了会下个软件然后打开运行下,啥都不会。而fiddler2只能解决最初级的问题。

我得先解释下什么是proxy。proxy分两种,正向(forward)和反向(reverse)。正向代理是给最终用户用的,填在浏览器、iphone的网络设置里,当你访问任何一个网页的时候,请求先发给代理服务器,然后由这个代理服务器再转出去。反向代理是给网站服务器用的,假如我们有一个网站,它的服务器只有内网IP,但是又希望能从外网访问,那么就找一个有公网IP的服务器,在它上面用nginx、squid、varnish之类的工具反向代理到内网来。反向代理对最终用户是不可见的。

Fidder2是一个正向代理,也就是说,需要用户把它的IP和端口号填在iphone的网络设置里(就在填wifi密码的那个界面)。然后当打开浏览器上网的时候,如果浏览器检测到代理设置,那么它发出的HTTP请求的path部分就是一个full url。如

本来request应该发送:

GET / HTTP/1.1
Host: www.baidu.com

因为要使用代理,所以request就变成:

GET http://www.baidu.com/ HTTP/1.1
Host: proxy.example.com

我当时抓sina 微博客户端的包就是用fiddler这么干的。但是呢,如果软件本身不支持代理,这么搞就行不通了。于是我们需要的是反向代理而不是正向代理。

fiddler2本身也可以当反向代理用。比如我在iphone上把某个目标网站的域名用hosts文件指向我的win7(192.168.137.1),然后让fiddler2监听在80端口。也可。但是缺点是fiddler2 并不支持HTTPS的反向代理。

要给HTTPS做反向代理,说起来也挺容易。用CA证书给目标网站生一个假的ssl证书,然后用Apache/nginx配置一个反向代理到fiddler2即可。不过这样的话,很复杂,而且只能截取一个网站。能不能批量的全搞了呢?

还有种东西,叫透明代理(transparent proxy)。我在potato公司工作时,每当我打开一个网页,http请求都是从一个squid透明代理出去的。我们可以在网关上,简单的把所有80端口的通信全部转发到某一个squid上。如果这些http请求都带有Host字段,那么squid就能根据这个字段做域名解析然后连接到目标服务器,把内容抓下来,返回给原始的请求者。如果不含有Host字段,那就只能借助于iptables在转发时想办法传递更多的信息过去。具体请参见tproxy的文档。

但是squid在给https做透明代理的时候,功能还没做完,目前基本不可用。因为此时一个难点是,ssl握手的时候,证书怎么生?如果client没有发送SNI信息过来,那么就得去目标网站上抓证书,得到common name之后,据此现生一个。

最后,我在网上找了个现成的工具,虽然装起来很麻烦,用起来还不错。 http://mitmproxy.org/。等我有空了重新写一个吧。

装好mitmproxy这个工具后,首先打开ip_forward

sysctl -w net.ipv4.ip_forward=1

然后用iptables设置下NAT:

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

然后启动proxy:

mitmproxy -T --host

不过 这些我都是在虚拟机里面干的。windows7哪来的iptables啊。最后一个问题,怎么让我的iphone的网络流量全走到这个虚拟机里面来呢?VPN。

搭VPN我最熟了,刷刷,3分钟,ipsec搞定。但是连不上… 身份认证失败… 查了很久,靠,原来是selinux没关。

此博客中的热门博文

在windows下使用llvm+clang

少写代码,多读别人写的代码

tensorflow distributed runtime初窥