@EricaHe
2015-12-03T06:24:50.000000Z
字数 3420
阅读 944
读书笔记
SSL
发生实现错误的一些原因:
两步基本检查:
而一个更完备的实现将会做更多的检查,如所有的密钥都是健壮的,那些弱签名(如MD2、MD5、(很快还会有)SHA1)没有被使用等等。
这虽然说起来简单,但在实际操作的时候,会有更多的细节上的问题。
例子
Microsoft CryptoAPI (2002)
基本检查失败——导致任意合法的服务器证书可以用来给一些伪造证书签名,从而使其能够被信任。
Moxie Marlinspike发现了这个问题,并写了sslsniff来证明该漏洞可被利用,而在2009年,他又发现说OpenSSL(版本大约是0.9.6)也存在这个问题。
GnuTLS (2008)
证书链检查失败——只需在任何不被信任的证书链后添加任何一张可信的根证书,就能够使该证书链通过检查。这个错误的产生原因是由于最后添加的那张根证书,使得检查证书链上的所有证书这一步骤被跳过了。
OpenSSL (2009)
DSA和ECDSA签名检查失败——导致任何一名中间人可以通过出示一条虚假的证书链便能够通过验证。
iOS (2011)
基本检查失败——iOS4.2.10之前的版本和4.3.5中,苹果没有检查证书是否被允许作为下级CA,从而使得叶子证书可以为任何其他的证书签名。
iOS and OS X (2014)
连接验证失败——在连接验证中的一些错误代码,使得一名中间人攻击者能够静默劫持任何DHE和ECDHE连接。这个问题来自于握手过程中一个极为短暂的、并没有被记录的过程,波及了iOS6.x和部分iOS7.x版本(在iOS7.0.6中得到修复),以及OS X 10.9(在10.9.2中得到修复),除了部分跨平台的、使用其自己的TLS栈的应用(如Chrome和Firefox),所有运行于受影响系统上的应用都受到其威胁。
GnuTLS (2014)
证书链检查失败:
1. 任何version1的X.509证书被当做一张中间CA证书处理了。持有一张合法v1格式服务器证书的攻击者可以伪装成任意的服务器。(GnuTLS 2.11.5)
2. 一个与苹果公司类似的问题,导致一张伪造的证书可以短路掉整个验证过程,并被认为是合法的。
OpenSSL(2014)
ChangeCipherSpec注入——攻击者可以在两个OpenSSL终端的握手过程中注入ChangeCipherSpec消息,强制协商一个可预测的密钥。这个问题几乎存在于所有的OpenSSL版本,但只有当OpenSSL1.0.1运行于服务器上时,才能够被利用。
造成这个问题的主要原因是,ChangeCipherSpec消息被用来标志结束协商、转向加密的过程,但由于这一消息不是握手协议中的一步,所以OpenSSL并没有对此进行认证。
在应用中,许多SSL证书检查也存在问题,详细可参看The most dangerous code in the world: validating SSL certicates in non-browser software一文。
该份论文认为造成应用端SSL证书检查的问题根源,不仅仅在于那些库本身就不安全,也是由于使用文档写得太过糟糕,以至于开发者很难写出安全的代码。
不过也有些平台做的非常好,比如Java的SSL/TLS实现
(JSSE),几乎实施了每一个必要的验证步骤。
这一步中有一个关键问题——对于NUL字节的处理,由于不同平台下对于字符串的处理方式不同,导致了一些安全问题。
在C中,NUL用来标志字符串的结束,其本身并不是数据的一部分。
然而在证书结构中,ASN.1才是标准,所有的结构都是连同其长度一起被储存下来的。
问题就发生在这两者之间:证书可能是有ASN.1进行编码的,但却用C来对此进行处理。
攻击方式:
创建一个在hostname中存在有NUL字节的证书,大多数用户会认为到这里hostname就结束了,于是NUL字节就会截断CA验证的过程。
例子
随机数生成是非常重要的一块,一个好的随机数生成算法,例如一个256位的对称密钥,应该能够构建出一个256位空间,但如果该算法存在问题,则很可能构建出一个只有32位的空间,从而使得安全程度大大降低。
Netscape Navigator (1994)
Netscape Navigator根据从启动开始的毫秒数和操作系统的进程以及父进程的ID来生成随机数。
如果攻击者与受害者在同一台机器上,那么攻击者就能够决定进程和父进程的ID,至于从启动开始的毫秒数,攻击者可以根据他们上网时发送包的情况对其进行猜解,猜解空间大概在20位左右,攻击者可以在约25秒内猜解出其值。
如果考虑更加一般的情况,即攻击者与受害者并不在同一台机器上,从而使得攻击者不知道受害者的进程和父进程ID,在这样的情况下,密钥空间将会有47位——即便在当时,这也在暴力破解的能力范围内。
Debian (2006)
这个错误主要来自于一行被不小心注释掉的代码,导致随机数生成器的熵的来源只剩下了一些从进程的ID获得的辅助输入,使得所有加密操作的熵只有16位这么大。
/*
* Don't add uninitialised data.
MD_Update(&m,buf,j);
*/
MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
MD_Final(&m,local_md);
md_c[1]++;
由此导致最大的问题是OpenSSH的弱密钥,不过好在这些密钥都被存储在一个地方,可以方便地访问查看,所以Debian建立了一份黑名单以及一些工具来发现它们。
但替换TLS弱密钥要困难得多,因为这不是一个自动化的过程。已经有程序开始扫描所有文件并检测出弱密钥。由于这个问题可以从服务器的公钥上被发现,所以也有远程测试工具被开发出来。另外,由于大部分的服务器证书都只有一到两年的有效期,所以CA可以拒绝向弱的私钥发放证书。然而,虽然有这些工具,但有很多人报告说,这些工具并不能正确地标记出弱密钥。
嵌入式设备
许多嵌入式设备中的密钥因随机数发生器而存在安全隐患,占据0.5%的RSA密钥和1.03%的DSA密钥。
这些问题可以归结如下:
1. 默认密钥:许多厂家在发布产品时,直接使用了默认密钥,这使得所有该厂的产品都含有相同密钥,从而攻击者可以从硬件或者软件中提取出密钥,去攻击该厂的其他产品。
2. 由于熵过低而导致的重复密钥:一些设备在初次启动时就开始生成密钥,而此时的熵并不足以保证其安全性,导致其密钥是可预测的。
3. 可因式分解的密钥:有人发现,许多RSA密钥中,构成该密钥的两个素数,有一个大家都是相同的,这使得该密钥可能被破解。根据一些研究表明,这个问题的根本原因在于OpenSSL中在低熵的条件下就生成了密钥。
Heartbleed是OpenSSL中一个灾难性的漏洞,主要针对的是TLS协议扩展中一个叫Heartbeat的协议。
由于在代码中缺少了对于读取长度的检查,使得攻击者可以在一次heartbeat请求中获取到64KB的服务器进程内存,通过提交多次请求,攻击者可以无止境地获得内存的快照,一旦有敏感信息,攻击者就可以轻易获取。
波及面
OpenSSL versions 1.0.1到1.0.1f,而更早的0.9.x及1.0.0版本则不受影响——据估计,在该漏洞刚刚被发现时,全世界范围内大约17%的服务器有此漏洞,不过该漏洞以前所未有的速度被大范围地修补了。
后续措施
1. 升级OpenSSL至最新版本,或关闭OpenSSL的heartbeat协议
2. 嵌入使用了OpenSSL的产品需要发布补丁
3. 关注那些可能已经泄露的敏感数据,至少要更换私钥和证书,之后再考虑session ticket key以及用户密码等秘密
4. 前向保密——这使得即使服务器的私钥被破解,攻击者也不能解密出过去的会话。