苹果 SSL/TLS Bug的细节

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

近日,苹果向iOS用户推送了一个安全更新,指出在iOS系统中SSL/TLS安全连接存在严重的bug,但并没有给出更详细的说明。对此问题的解答已经出现在Hacker News的头条,我想大家都已经知道了这个漏洞,也不需要再胡乱猜测了。
  以下就是导致这个bug的一段代码:

static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
OSStatus        err;
...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
...
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}

  注意其中有两个连续的go to fail语句,第一个会正确地在if判断为真时执行,但是第二个却在任意情况下都会执行,尽管它有着看似标准的语句缩进。于是当代码跳转至fail时,由于认证使用的final方法还未执行,而update方法执行成功,因此err会包含一个校验成功的信息,导致对签名的认证永远不会失败。
  认证签名时将会检测ServerKeyExchange消息中的签名,它用于DHE和ECDHE加密套件(多种加密算法联合使用)在建立连接时获取会话密钥(ephemeral key,本次会话的临时密钥)。服务器告诉客户端:“这是给你的会话密钥和签名,通过我的证书,你可以确定密钥和签名是来自于我的。”而现在会话密钥和证书链之间的关联已经断裂,所有曾经安全的认证都不再有效。这意味着,服务器可以向客户端发送正确的证书链,但在连接握手的过程中使用错误的私钥进行签名甚至干脆不签名,因为我们无法确认这个服务器是否持有对应此证书的正确的私钥。
  这个Bug出现在SecureTransport的代码中,它将影响iOS的某个早期版本直到7.0.6(其中7.0.4我已经确认过),同时也会影响OS X系统(在10.9.1上已经得到确认)。所有使用了SecureTransport的地方都会被波及到,也就等于是绝大部分苹果系统上的软件。Chrome和Firefox在SSL/TLS连接中使用的NSS,因此得以幸免。然而如果你的软件更新程序使用了SecureTransport,那么前面的讨论都不能说明什么了。(译注:更新程序可能连接到仿冒主机。)
  对此我构建了一个简单的测试网站。注意端口号(1226是这个漏洞在CVE里的编号),443端口运行着一个正常的网站,而1226端口的网站将会发送使用错误私钥签名的证书。如果你使用https连接去访问,就能够重现这个bug。
  即使证书链是正确的,由于它和连接握手之间的关联已经被破坏,我认为任何形式的证书锁定都无法阻止这种错误的认证。同时,这个bug不仅仅影响使用DHE或者ECDHE加密套件的网站,因为攻击者可以自行选择合适的加密套件。
  在TLS 1.2的针对ServerKeyExchange消息的认证是使用的另一个方法,因此没有受到影响。但仍然有上面提到的问题,攻击者可以选择任何客户端能够使用的版本。当然如果客户端仅支持TLS 1.2,那就完全没有问题了。客户端也可以只使用明文-RSA加密套件,那么就不存在ServerKeyExchange消息,同样起到了防范的效果。(当然在这两种方法中,前一种更加可取。)
  根据我的测试发现,iOS 7.0.6已经修复了这个问题,但是在OS X 10.9.1中仍然存在。(补充:好像这个bug在OS X系统中是在10.9版引入的,但是iOS6的某些版本中就早已出现了。iOS 6.1.6昨天修复了此bug。)这样潜伏在代码深处的bug简直就是一个噩梦。我相信这仅仅是个失误,但无论是谁手滑(手贱)把这样的代码写出来,我都为他感到深切的悲痛。
  下面是一段和这个bug有相同问题的代码:

extern int f();
int g() {
int ret = 1;
goto out;
ret = f();
out:
return ret;
}

  如果我编译时候加上参数-Wall(启用所有警告),在Xcode中无论是GCC 4.8.2还是Clang 3.3都没有对死代码发出警告,对此我非常惊讶。更好的编译警告本可以阻止这样的悲剧,又或许在实际编码中这类警告发生第一类错误(弃真错误)的概率太高?(感谢Peter Nelson指出在Clang可以使用-Wunreachable-code参数对这样的问题发出警告,而不是-Wall。)
  看起来是允许if代码块不使用大括号才导致了这样的代码风格,但是有人在大括号里也可能使用错误的代码缩进,因此我也没觉得大括号带来了多少便利。
  写一个测试用例本可以发现这个问题,但是由于它深嵌在连接握手的过程中,所以非常复杂。这个用例需要写一个完全独立的TLS栈,并且包含大量发送无效握手请求的配置。在Chromium中我们有个修改过的TLSLite工具可以做类似的测试,但是我不太记得我们的用例是否完全适用于这个bug的情况。(如果不行的话,听起来好像我已经知道周一早上要干嘛了)(译注:当然是把用例改到可以完全适用)
  代码审查对发现这类bug非常有效。不仅仅是浏览审阅,而是审查每句新写的代码。我不知道苹果一般怎么做代码审查,但是我充分相信我的同事,Wan-Teh和Ryan Sleevi。如果我意外手滑,他们一定会及时发现。可惜不是每个人都有幸和这样的同事一起工作。
  最近,针对苹果忽略对证书中主机的校验这个事情,有一系列讨论。的确在OS X中使用curl时,即使IP地址不在证书中,命令行也会接受和这个主机的连接。然而我没找到更多问题了,Safari也没有受到影响。

最新内容请见作者的GitHub页:http://qaseven.github.io/

相关文章
|
14天前
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
|
4月前
|
安全 网络安全 数据安全/隐私保护
SSL/TLS证书**是一种用于加密网络通信的数字证书
SSL/TLS证书**是一种用于加密网络通信的数字证书
185 6
|
7天前
|
安全 算法 网络安全
SSL/TLS:构建数字世界的加密长城
**协议演进:从网景实验室到全球标准** 1994年,网景公司推出SSL协议,首次实现40位密钥加密传输,开启网络安全新纪元。此后,SSL 3.0、TLS 1.0相继问世,至2018年TLS 1.3将握手速度提升60%,强制前向加密确保历史会话安全。TLS协议通过非对称加密、对称加密和证书信任链等多层架构保障通信安全。2014年POODLE漏洞促使全行业禁用SSL 3.0,催生防降级机制。
|
11天前
|
安全 算法 物联网
SSL/TLS:互联网通信的加密基石与安全实践
**简介:** 在数字化时代,互联网每天传输海量敏感数据,网络攻击频发。SSL/TLS协议作为网络安全的基石,通过加密技术确保数据安全传输。本文解析SSL/TLS的技术架构、密码学原理、应用场景及常见误区,探讨其在未来的发展趋势,强调持续演进以应对新型威胁的重要性。 SSL/TLS不仅保障Web安全,还广泛应用于API、邮件、物联网等领域,并遵循合规标准如PCI DSS和GDPR。
|
4月前
|
安全 算法 网络安全
SSL/TLS协议是什么?
SSL/TLS协议是什么?
294 57
|
4月前
|
缓存 安全 算法
SSL和TLS部署实践
在TLS中,所有安全性都以服务器的加密身份开始,这就需要一个强大的私钥来防止攻击者进行模拟攻击。同样重要的是拥有一个有效和强大的证书,它会授予私钥来代表一个特定的主机名。
108 2
|
4月前
|
存储 安全 算法
SSL和TLS部署实践
【10月更文挑战第28天】在TLS中,服务器的加密身份和强大私钥是安全基础,2048位RSA密钥足以满足大多数需求。保护私钥需在可信环境生成、加密存储、使用HSM、及时撤销旧证书、每年更新证书。确保证书覆盖所有域名,选择可靠CA,使用SHA256签名算法,配置完整证书链,禁用不安全加密套件,启用前向保密,使用会话重用机制,启用OCSP Stapling,加密整个网站,删除混合内容,安全设置Cookie,配置HSTS和CSP。
408 1
|
5月前
|
安全 网络安全 数据安全/隐私保护
【Azure Developer】System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
|
5月前
|
JavaScript 安全 Java
谈谈UDP、HTTP、SSL、TLS协议在java中的实际应用
下面我将详细介绍UDP、HTTP、SSL、TLS协议及其工作原理,并提供Java代码示例(由于Deno是一个基于Node.js的运行时,Java代码无法直接在Deno中运行,但可以通过理解Java示例来类比Deno中的实现)。
134 1
|
7月前
|
监控 安全 Linux
在Linux中,如何管理SSL/TLS证书?
在Linux中,如何管理SSL/TLS证书?