HTTPS抓包与中间人攻击原理详解
HTTPS抓包与中间人攻击原理详解
从HTTP到HTTPS,无疑是安全性上很大的一次升级。为了搞清楚HTTPS抓包的原理,我们首先需要回顾一下HTTP到HTTPS的演变过程。
HTTP 抓包
由于HTTP协议是明文传输的,我们可以非常容易地获取到HTTP请求的内容。我们可以通过设置代理服务器(proxy)或在路由器等设备中插入截取程序,轻松获取HTTP数据包的内容。
我们使用最著名的网络协议分析工具Wireshark进行分析。在访问http://www.baidu.com
后,可以轻松截获HTTP的明文内容。
HTTPS的改进
由于HTTP协议的明文传输存在安全风险,HTTPS(HTTP Secure)使用了多个加密协议对HTTP通信进行加密,保证了数据内容的安全性,并在一定程度上防止了中间人攻击。HTTPS的通信过程相对复杂,这里以最常见的TLS 1.2版本协议为例,大致分为以下几步:
- 客户端发起HTTPS通信(ClientHello),包括支持的加密套件、key_share携带一个client random等信息。
- 服务端接收到之后,会做出响应(ServerHello),分批次发送server random、证书、公钥、支持的加密套件、支持的加密协议版本等信息。
- 证书校验与预加密:
- 客户端在接受到ServerHello之后需要校验证书(当然你也可以主动选择跳过)。证书如果是通过证书授权机构签章的,那么你不需要安装任何认证授权(Certificate Authority),你的手机电脑里自带的CA将会识别出证书的真伪,以此来防止中间人攻击。
- 客户端从服务端支持的加密套件和协议中挑选一个自己适配的。
- 客户端产生一个pre master secret并使用服务端发的公钥进行加密。
- 将加密的pre master secret以及最终敲定的加密套件发送给服务端。
- 服务端接受到加密后的pre master secret后使用自己的私钥对其进行解密。这时服务端和客户端同时拥有了三组随机数:client random、server random、pre master secret,然后告诉客户端,已经可以进行加密通信了。
- 之后客户端和服务端之间使用敲定的加密算法对client random、server random、pre master secret进行加密生成master secret进行对称加密通信即可。
协议的具体细节可以参考相关资料。我们在使用抓包工具访问https://www.baidu.com
的请求内容时可以发现,经过HTTPS握手之后,数据变成了不可读的加密数据(下图中的encrypted Application data)。
中间人攻击
我们知道HTTPS是端到端的加密,我们无法像HTTP代理那样中途获取并查看数据流的内容。那么我们如何才能抓取到数据呢?我们可以使用中间人攻击技术(man-in-the-middle,简称MITM)。
在HTTPS部分,我提到客户端需要对证书进行校验,这可以防止中间人攻击。那么如何解决证书校验的问题呢?其实我们可以伪造一个相同特征的证书,这个证书使用中间人的CA私钥进行签名,然后将CA公钥安装到Client上(当然第三方证书的安装并不容易,需要操作系统进行用户授权,让用户知道自己在进行危险操作),用中间人CA公钥进行验签,这样就骗过了客户端自己就是服务端。由于服务端不会验证客户端的真伪,中间人只需要伪装成一个客户端进行访问即可。
实际上整个过程会更复杂一些,我们使用图解来进行详细过程的描述。
- 客户端发起一个HTTP CONNECT请求
- 中间人进行响应,让客户端感觉好像和服务端连接上了
- 客户端相信自己已经和服务端呼应上了,然后开始发起TLS连接,并且携带SNI(作用是告诉服务端需要那个host的证书)
- 中间人仿冒了客户端的请求内容,和服务器进行SSL连接
- 服务器返回匹配的证书,这其中包含CN和SANs(相当于证书支持的域名,用户客户端检查服务端返回的域名是否可用),我们根据返回的证书信息仿造一个相似的证书
- 使用仿造的信息对step3进行回应
- 客户端发送TLS建立完成的请求
- 中间人发送TLS建立完成的请求
抓包工具
目前市面上有很多工具可以使用,老派的桌面工具有Fidller、Charles,性能稍差,但是安装容易。熟悉JavaScript也可以使用国人开发的Whistle。我个人比较喜欢基于Python的Mitmproxy。
这里使用Mitmproxy,进行证书配置后,就可以抓到HTTPS的内容了。我们对比证书可以发现,实际服务端证书签发者从GlobalSign,变成了Mitmproxy,这也是HTTPS抓包最核心的一步。