大家好,我是 世奇,笔名 ConardLi

3月27日 Github 疑似遭受大规模攻击, desktop.github.com 、 pages.github.com 、 *.github.io 等多个站点均提示 “您的连接不是私密连接”,并且电信、移动、联通、教育网均可复现该问题。

这里我就从网络协议的角度来帮大家分析一下本次攻击事件,网络永远是不安全的,攻击方式多种多样,以下的分析是我认为可能性比较大的一种方式,大家有什么问题欢迎后台私信我~

图片

为什么强制 Https 访问

你在访问 http://github.com 的时候,会发现浏览器只允许你通过 HTTPS 访问,这是因为 Github 开启了 HSTS,它告诉浏览器只能通过 HTTPS 访问。

如果开启了 HSTS,你可以在控制台看到 Strict-Transport-Security 这个标头:

图片

这个请求头可以设置下面几个属性:

  • max-age=<expire-time>:设置在浏览器收到这个请求后的<expire-time>秒的时间内凡是访问这个域名下的请求都使用HTTPS请求。
  • includeSubDomains(可选):如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
  • preload 支持预加载 HSTS

如果一个网站接受一个 HTTP 的请求,然后跳转到 HTTPS,用户可能在开始跳转前,通过没有加密的方式和服务器对话,比如,用户输入 http://github.com 或者直接 github.com

这样存在中间人攻击潜在威胁,跳转过程可能被恶意网站利用来直接接触用户信息,而不是原来的加密信息。

用户首次使用HTTPS访问站点,并返回Strict-Transport-Security标头时,浏览器会记录此信息,以便将来使用HTTP加载站点的尝试将自动使用HTTPS.

Strict-Transport-Security标头指定的到期时间过去时,下一次尝试通过HTTP加载站点的尝试将照常进行,而不是自动使用HTTPS.

所以,github 开启了 HSTS 意味着我们只能从用 HTTPS 来访问它,但是这时候站点的中间某个环节出了问题导致无法建立安全链接,所以无法访问,那么浏览器是如何与服务端建立安全链接的呢?

浏览器如何建立安全链接

客户端和服务端建立安全连接,一般需要经历以下几个步骤:

  • 客户端给出协议的版本号、一个客户端生成的随机数和客户端支持的加密算法;
  • 服务端在客户端给出的加密算法列表中选出一种,并给出数字证书和一个服务端生成的额随机数;
  • 客户端确认数字证书的有效性,然后生成一个新的随机数,并使用数字证书中的公钥加密这个随机数;
  • 服务端使用私钥解密,获取客户端发来的随机数;
  • 客户端和服务端根据约定的加密方法,使用之前的三个随机数,生成对话密钥,这个密钥会用来加密接下来的整个通信过程。

实际上这里的过程复杂的多,这里我只简要描述一下过程,就不展开讲了,看了很多解释,还是《图解 HTTP》的解释最为经典:

图片

那么,以上任何一个步骤出了问题,浏览器都不能建立安全链接。

当浏览器出现 “您的连接不是私密连接” 这种情况,一般就是浏览器校验证书出了了问题,那么浏览器如何验证SSL/TLS证书有效呢?

浏览器如何验证SSL/TLS证书有效?

图片

  • 检查证书是否是由浏览器中“受信任的根证书颁发机构”颁发

每一张证书都是由上级CA证书签发的,上级CA证书可能还有上级,最后会找到根证书。最终浏览器会验证证书是否是由浏览器中“受信任的根证书颁发机构”颁发。

  • 检查证书中的证书吊销列表,检查证书是否被证书颁发机构吊销

证书吊销列表(CRL)证书被吊销后会被记录在CRL中,CA会定期发布CRL。应用程序可以依靠CRL来检查证书是否被吊销了。

  • 通过在线证书状态协议检测证书是否有效

在线证书状态协议(OCSP)。除了证书吊销列表离线文件,证书颁发者也会提供实时的查询接口,查询某个特定证书目前是否有效。实时查询的问题在于浏览器需要等待这个查询结束才能继续TLS握手,延迟会更大。以上是站点在证书颁发者的角度说明会提供的两种判断方式,实际情况下浏览器究竟会选择哪种方式判断。

  • 检查此证书是否过期

证书中会包含证书的有效期的起始时间和结束时间,取其中一个即可判断。

  • 检查部署此证书的网站的域名是否与证书中的域名一致
  • IE7浏览器会到欺诈网站数据库查询此网站是否已经被列入欺诈网站黑名单

浏览器需经过以上几个方面的检查后,才会在页面显示安全锁标志,正常显示部署了SSL/TLS证书的加密页面。

如果这期间任何一个流程验证出错,那么浏览器就无法建立安全链接,最终提示 “您的连接不是私密连接”。

打开这个不受信任的证书,显示该证书的颁布者是346608453@qq.com

图片

查询该QQ号码,显示其昵称为心即山灵,地址为黑龙江哈尔滨。打开他的QQ空间,发现他发了一条动态说自己的QQ被盗了,这里很明显有点掩盗铃的感觉,因为攻击者要生成CA证书的话,随便填个邮箱都可以,还需要盗你的号么?

图片

从攻击者自签名证书留下的QQ号可以在网上搜寻到部分信息,信息显示此前这名攻击者正在学习加密技术。这名攻击者还曾在技术交流网站求助他人发送相关源代码,从已知信息判断攻击者可能是在学习后尝试发起攻击。看了看这老哥的留言,已经火了。。

图片

很显然,这个证书被劫持了,而且这个证书肯定是不会被浏览器信任的,这才会导致浏览器无法建立安全链接,从而访问失败。

然而问题又来了,三大运营商纷纷中招,什么样的攻击能控制如此大的范围呢?

BGP 劫持

BGP 表示边界网关协议,它是 Internet 的路由协议,它提供了方向,以便流量尽可能有效地从一个 IP 地址传播到另一个 IP 地址。换句话说,它帮助我们高效地查找 A 服务器到 B 服务器的最佳路由路径。DNS(域名系统)服务器提供 IP 地址,但是 BGP 提供了最有效的方法来访问该 IP 地址。粗略地说,如果 DNSInternet 的通讯簿,则 BGPInternet 的路线图。

AS 指的是一个区域中大量计算机组成的网络,中国各家运营商管理着相应的 AS

BGP 劫持就是某些 AS 通过宣称自己拥有某个 IP 地址,而将对该 IP 地址的请求引向一些恶意服务器。

这里参考下一位知乎网友的图,画的很清晰:

图片

用户知道 github.comIP 地址后,从 AS 1 出发,正常来说,应该访问在 AS 4 的 Github 服务器,但是 AS 5AS 6 欺骗 BGP 它拥有 github.comIP 地址并且误导 BGP 的路径经过它,于是用户变成访问 AS 6 服务器,但是用户还以为自己连接的是正确的服务器(根据 IP 地址)。万幸的是,由于 AS 6 的服务器无法提供正确的 Github 证书。所以 HTTPS 连接无法正确建立。

攻击者使用 BGP 劫持将 github.comIP 指向了使用 346608453@qq.com 自签名的证书的服务器,由于浏览器无法信任该证书,导致页面访问失败,这就是整个事件的原因了。。

图片

因为 BGP 提供了最有效的方法来访问该 IP 地址,所以BGP劫持几乎是不可能停止的,想象一下,如果没有人在看高速公路标志,唯一的方式告诉如果他们被恶意更改是通过观察,很多汽车最终在错误的社区。然而,为了使劫持发生,攻击者需要控制或破坏连接一个自治系统(AS)和另一个自治系统(AS)的启用了BGP的路由器,因此不是每个人都可以执行BGP劫持。

这样的事情早就不是第一次发生,2008 年巴基斯坦的 ISP 运营商就使用 BGP 劫持屏蔽用户浏览 Youtube2018 年,黑客通过 BGP 劫持将重定向了亚马逊 DNS 服务器的流量,然后盗取加密货币。

如果你想加入高质量前端交流群,或者你有任何其他事情想和我交流也可以添加我的个人微信 ConardLi