# SSL/TLS协议安全系列- SSL中间人攻击防范方案概述

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2015-11-16T02:47:00Z
Canonical: https://wepostx.com/topics/1180

> 乌云历史资料归档
>
> **原始作者：** GoSSIP_SJTU
> **原始编号：** superkieran-wooyundrops:890
> **原始发布时间：** 2015-11-16 10:47
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

Author:张天陆

# 0x00 简述

基于PKI体系的SSL/TLS协议近年来暴出很多安全问题，比如著名的HeartBleed、POODLE攻击和Freak攻击等，2014年关于SSL/TLS协议证书验证问题的CVE有成千个。针对SSL协议在实现中暴露出的各种问题，这里我们讨论一下现有的加固和防范方案，主要包括四个方面：
a) Key pinning策略
b) HSTS策略
c) 多路径证书检查策略
d) DNS-based authentication
下面我们基于这四个策略做详细介绍。

# 0x01 Key Pinning策略

## 1、 Key Pinning介绍
Pinning是把服务器的主机名和证书、公钥等密码学要素联系起来的一种安全技术。例如，当知道某网站的正确证书，再次链接此网站时，可以通过对比已知的正确证书和从网站接收到的证书，判断是否被中间人攻击。当然，没有必要在本地保存某网站的完整证书信息，可以对证书做hash（比如SHA-256），本地保存对应的hash值，这样比完整证书更便捷，并且节省空间。
相对证书pinning，更为实际的是public key pinning，因为很多时候证书在重新签发时，并没有更换其公钥信息，这也是为什么很多证书拥有相同公钥的原因。这样如果在本地pin的是公钥信息，那么收到不同的证书也没关系，只要公钥内容相同，就可以信任这些证书。
对于SSH此类不依赖于证书的协议，可以直接pin公钥，但是对于SSL/TLS协议，最好的方式是pin X.509证书的SPKI（SubjectPublicKeyInfo）部分对应的hash值，SPKI部分包含了公钥以及其他额外的用于安全验证的信息（包括所使用的公钥加密算法、公钥位数）。

## 2、 pin的位置
服务器基于安全考虑，会经常更换公私钥对；并且如果私钥泄露，也需要从CA重新签发证书；并且同一个网站有可能部署了多个公私钥对。而如果pin的是服务器的公钥，那么在维护和使用上会相当复杂。
基于上述因素的考虑，可以将pin的位置放在证书链上。一般来说证书链开始于终端证书，有一个中间CA证书，最后是根CA证书。如果pin的是后两个证书信息（中间CA或者根CA的证书信息），那么服务器终端更换证书时，只要是同一个CA签发的，那么证书链没变，pin的信息也不用更换。
但是这里会出现另一个问题，CA可能会有很多的上级中间CA，或者不同的根CA，服务器在更换证书时，即使选择的是相同CA，那么上级中间CA有可能不同。
基于这些考虑，最佳的pin位置可以选择在证书链的第二个证书上，就是给服务器签发证书的CA的证书，因为即使服务器更换证书，也会选择该CA进行证书签发，pin的信息不会变。

## 3、何时用pin
最有效的pinning方式，是在native application中。因为这时作为开发者可以控制通信双方，对于桌面应用和移动应用都可以，比如一些银行软件，支付软件等。
对于这种情况，如果开发者可以控制通信双方（客户端与服务器），从而既可以使用自己的证书作为pinning信息，也可以使用第三方CA签发的证书。

## 4、使用key pinning的不足：

- 服务器私钥如果泄露，就需要更换密钥对，另外服务器会经常更改密钥对，为了使相同密钥加密的信息不要太多。这时就需要经常的更换pin的信息，操作复杂。

- 另外同一站点有可能有多个证书，pinning的内容如果不全面，有可能产生错误信息。

- 对于一些应用在更换pin信息时，需要通过软件升级的方式，不太方便。

# 0x02 HSTS策略

## 1、 HSTS简介
HSTS（HTTP Strict Transport Security）HTTP严格传输安全，最早于2009年提出，标准化于2012年11月的RFC 6797，是一套由互联网工程任务组发布的互联网安全策略机制。网站可以选择使用HSTS策略，强制浏览器使用TLS协议，并且中断所有证书出现错误的连接，从而减轻浏览器在执行TLS协议时所面临的一些危险。
HSTS策略的使用，主要解决了以下几个问题：

- 面对一个主机名（没有指明协议），浏览器不知道该网站是否使用TLS协议；

- 当遇到证书错误不是阻断连接，而是给用户告警（用户多会选择忽略）；

- HTTPS页面从一个HTTP origin加载资源，被称为mixed content，攻击者可以通过控制从不安全页面加载到https页面的mix content实现攻击效果；

- cookie遵守的同源策略和web content的同源策略不同，只根据host隔离，因此https和http会共用cookie。
HSTS通过两种方式，解决以上问题：

- 在本地将所有的http转换为https，保证使用了HSTS的网站，只能通过https访问；

- 当遇到证书错误时，中断链接。

## 2、HSTS安全意义
一些支持https的网站一般情况下也会监听http的请求，之后再讲这些请求重定向为https。例如：当收到http://www.facebook.com时，会将用户访问重定向为https://www.facebook.com。这种重定向是不安全的，因为第一个请求使用的是http，攻击者可以从中获取一些敏感信息（比如之前安全会话中的coocie等），另外，攻击者还可能将用户重定向到一些钓鱼网站。并且根据用户的输入习惯，不会在主机名前加上https，更容易带来威胁。
HSTS策略防止了这种威胁的存在，它要求浏览器在本地将http协议强制转换为https，之后再与服务器通过https协议进行通信。

## 3、HSTS执行
服务器开启HSTS的方法是，当客户端通过HTTPS发出请求时，在服务器返回的超文本传输协议响应头中包含Strict-Transport-Security字段（非加密传输时设置的HSTS字段无效，Strict-Transport-Security 头信息当通过HTTP请求传递，会被浏览器忽略，因为攻击者可能拦截或者篡改HTTP连接头，直到第一次通过https进行安全连接，并且收到Strict-Transport-Security头信息，才会针对该网站配置HSTS策略，这里可以通过浏览器对HSTS preload方式解决）。
Strict-Transport-Security字段包括：

```text
Strict-Transport-Security: max-age=expireTime [; includeSubdomains]
```
其中：max-age参数指明了过期时间，单位秒，浏览器需要记住这个网站只能通过HTTPS访问的时间；includeSubdomains是可选参数，指明该网站的子域名也需要通过https访问。
浏览器对Strict-Transport-Security字段处理：
当浏览器使用https第一次访问网站，收到服务器响应的包含该字段的头，会记录下这些信息，之后在有效期内，把对该网站的请求都转换为https。每次浏览器收到Strict-Transport-Security头，都会更新max-age指定的有效期时间，这样可以防止HSTS策略过期。
我们用图形简单介绍HSTS功能：

![原文图片](/media/2016/06/dddc30143168fe93c1ca123a544c68c3)

图1
图1标示了正常情况下，服务器收到http请求时，重定向为https的过程，该过程是不安全的；

![原文图片](/media/2016/06/d57aa5a104bc8b87a1ba764944db3560)

图2
图2标示了第一次安全连接时，收到HSTS的Strict-Transport-Security头信息，之后的访问都会执行HSTS策略。

![原文图片](/media/2016/06/579a381f8fbee9f20b9940c4847a26d6)

图3
图3标示HSTS策略执行时的过程。

## 4、HSTS部署
HSTS的部署要考虑到全面性。默认情况下，HSTS只针对返回Strict-Transport-Security响应头的主机名部署，但是很多站点可以部署多个域名，因此要注意HSTS策略部署到所有的域名。
对于一些只有一个主机名的网站也需要考虑部署是否全面的问题。例如用户想要访问某网站时，没有加WWW前缀（输入XXX.com访问www.XXX.com），由于没法控制用户的输入，因此在配置HSTS时要注意覆盖到所有的主机名。
另外需要注意的是，HSTS部署的全面性要考虑到能够到达网站的所有的路径名，比如用户可能首先通过输入访问根域名，之后再访问其它子域名，此时根域名如果没有部署HSTS策略，有可能会招到SSL剥离攻击。

## 5、HSTS Preloading
当用户第一次正确使用https连接某网站，并且收到Strict-Transport-Security头时，才会根据头信息对该网站设置HSTS策略。为了提高HSTS的安全效率，解决“first visit”问题，Google安全团队在Chrome浏览器中设置了“HSTS preload list”，列表中的域名都会自动的使用HSTS策略。Firefox，Safari以及最新版本的IE浏览器，都会合并使用Chrome的HSTS preload list。
使用HSTS preload可以满足以下要求：

- 确保了根域名和子域名都被强制使用https；

- 对所有的子域名都标注了一个策略有效时间和preload标记，标示域名拥有者同意加入preload list中。
对于一些金融机构、政府网站或者社交网络等，HSTS策略可以缓解大量SSL/TLS协议遭受到的威胁。但是HSTS策略并不能低于证书伪造攻击，需要key-pinning策略协同使用。

# 0x03 多路径证书检测

多路径证书检查策略，核心思想就是不仅仅依赖PKI体系，抛开CA的权威性，通过多个途径和方法检验客户端收到的证书的合法性。
多路径证书检查的方法基本有两种：

- 公证人辅助证书检查；

- Tor-Network洋葱网络检查；

- Social network借助社交网络检查。
这里我们主要介绍前两种方法。

## 1、公证人辅助证书检查

### 1.1 Notary简介
公证人协助验证证书，是指通过第三方（Notaries）机构，协助验证证书是否合法有效。最早的出现是Perspectives，Firefox的一个插件，可以将收到的服务器证书与大量的notaries进行对比，这些notaries来自于不同的网络节点，这样即使其中某些节点出现问题，攻击者仍然没办法将所有的notaries攻破。通过对比证书是否相同，判断是否遭受中间人攻击。

![原文图片](/media/2016/06/2df0de91d12af5a5bca9fede1a77e63e)

图4
图4展示了利用notaries进行证书比对的流程，当客户端收到服务器返回的证书后，向设定好的多个notaries发出请求，根据服务器主机名查找多个notaries中对应的证书，通过返回的证书进行比对，如果有不相同，则认为该证书无效。这些notaries部署在不同的网络环境中。

### 1.2 Notaries证书获取
最初的Perspectives所对应的Notaries，会定期的主动的扫描全网的主机，从中获取证书所对应的公钥，存储在本地数据库中，当浏览器的Perspectives插件需要进行证书比对时，从该数据库中获取对应主机的证书公钥，返回给客户端进行比对。2011年，Convergence notary提供了类似的功能，不同的是Convergence notary不会主动的进行全网扫描，仅仅当客户端索求一个本地数据库中没有的证书时，才会向对应的主机进行证书索取。目前Perspectives和Convergence是两个权威的notary维护机构，各自维护这多个可以被共用的notaries。

### 1.3 Notaries的评估
使用Notaries作为第三方，协助进行公钥检查，浏览器可以通过插件完全的依赖所设定的可信Notaries，弱化了以X.509证书为基础的PKI体系。同时，如果某个Notaries被攻破，用户完全可以自行更改设置，选择不同的Notaries。
使用Notaries进行证书验证也有一些缺点：

- 降低了用户体验，多了一层证书验证流程，会降低网络访问速度；

- 对于一些Notaries，会获取到用户想要访问哪些网站的隐私；

- 一些网站可能会有多个证书，导致Notaries误报的情况出现。

## 2、Tor-Network 网络辅助证书检查
洋葱网络的特点是当用户访问某一个固定的目的端，每次经过的路径是随机的。具体来说，TOR客户端维护一个浏览器一样的代理，其他软件可以使用该代理提供的借口，进入Tor网络，TOR节点在不同次的连接时会选择不同的路径，不会轻易被中间人攻击。利用洋葱网络的这一特点，可以进行多路径证书检查。
洋葱网络辅助证书检查是建立在正常https协议出现证书警告的情况下，通过洋葱网络再次获取证书，比对两次得到的证书是否相同来判断是否遭受中间人攻击。

![原文图片](/media/2016/06/2331ac4d8513b2e9202a59add3c535c7)

图5
图5展示了使用Tor-Network进行多路径证书检查的流程：

- Alice收到https证书警告；

- 通过洋葱网络代理，接入洋葱网络；

- 获取目标服务器的证书；

- 比对两次获取的证书是否相同。
多路径证书检查的思想都是通过多一次的证书获取，与收到的证书进行对比，从而判断是否遭受中间人攻击，提高通信的安全性，但是这种方式势必会增加TLS连接消耗的时间，降低用户体验。

# 0x04 DNS-based authentication策略

## 4.1 DANE简介
DANE（DNS-Based Authentication of Named Entities）是一种将域名和密码学要素联合起来的安全标准，2012年8月在RFC 6698中标准化定义。域名拥有者可以控制DNS的配置，能够利用DNS作为单独的一条渠道来加强TLS的安全执行。DANE方便部署，但是仅靠DNS并不能提供任何安全性质，还需要依靠DNSSEC协议。
DNSSEC简言之，就是利用数字签名身份认证技术，在进行域名请求时，验证整个请求链中的每个DNS的身份，确保最终收到的域名信息是正确的没有被篡改过。
目前的认证机制分为两个阶段：一是有一群我们信任的第三方机构为域名真正拥有者签发证书，成为CA；二是客户端（比如浏览器）能够检测某主机名对应的证书是正确的。基于这种分离式的架构是因为通信双方一般是远距离没法碰面的，验证身份容易找到欺骗。而基于DNSSEC协议，DNS请求就可以确保安全性，就可以利用DNS提供身份验证，这样就有一个新的途径同域名拥有者进行通信，从而抛弃掉对CA的依赖性。
简言之，DANE就是在客户端pin主机名对应的的证书，之后通过DNS请求时，获取主机名的证书，通过对比判断证书的可信性。

## 4.2 DANE作用

- 安全的部署自签名证书
现在，自签名证书被认为是不安全的，因为没有一种办法区分自签名证书和中间人攻击伪造的证书，也就是说自签名证书都是一样的。但是，我们可以用安全的DNS去pin一个自签名的证书，这样浏览器就可以知道正在使用的自签名证书是安全的，也可以很容易的区分出中间人攻击伪造的证书。

- 安全的部署私有根证书 如果可以安全的pin一个服务器证书，那么也可以pin这个服务器证书所在的证书链中的任一证书，也就是说可以构造一个你所拥有的网站的根证书，并让客户端信任这个证书，这种方式对拥有很多网站的开发者来说，更为方便。

- 支持CA颁发的证书和Public key-pinning DANE无须改变现有的认证架构，同样的可以在客户端pin CA颁发的证书和根证书。

## 4.3 DANE执行
DANE扩展了一种新的DNS记录类型，叫做TLSA Resource Record(TLSA RR或者叫做TLSA)，TLSA包含四个区域：(1) Certificate Usage;(2)Selector;(3)Matching Type;(4)Certificate Association Data。
其中Certificate Usage字段有四种不同的值：
0-CA规范：pin一个CA，在证书链中必须有对应的CA签发的证书；
1-指定TLS证书：TLSA 记录指定应当用于某一域名的准确TLS证书；
2-信任点声明：在客户端pin一个某站点自己的CA，该CA可以不是公共信任的CA；
3-域名颁发证书：在客户端pin一个具体的TLS证书，该证书可以是某主机自己签发的证书
通过后两种值可以看出，DANE可以完美的支持自签名证书，同时也确保使用自签名证书的安全性。
自此，我们讲述了四种目前常见的SSL/TLS协议的加固策略，这四种策略固然各有优劣。其中key pinning可以和HSTS结合使用，确保强制使用https的同时也保证了证书安全性。另外，安全性和用户体验总是会存在一些冲突，在取和舍之间不同的人又有着不同的观点。

## Replies
