苹果 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/

相关文章
|
5月前
|
安全 网络安全 数据安全/隐私保护
顺便再来看看SSL/TLS
顺便再来看看SSL/TLS
62 0
|
2月前
|
监控 安全 Linux
在Linux中,如何管理SSL/TLS证书?
在Linux中,如何管理SSL/TLS证书?
|
20天前
|
消息中间件 安全 Kafka
Kafka支持SSL/TLS协议技术深度解析
SSL(Secure Socket Layer,安全套接层)及其继任者TLS(Transport Layer Security,传输层安全)是为网络通信提供安全及数据完整性的一种安全协议。这些协议在传输层对网络连接进行加密,确保数据在传输过程中不被窃取或篡改。
39 0
|
2月前
|
存储 Linux 网络安全
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Linux/Linux Container)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Linux/Linux Container)
|
2月前
|
网络安全 API 数据安全/隐私保护
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
|
2月前
|
安全 Linux 应用服务中间件
在Linux中,SSL/TLS证书的作用以及如何在Linux中管理它们?
在Linux中,SSL/TLS证书的作用以及如何在Linux中管理它们?
|
2月前
|
安全 网络安全 数据安全/隐私保护
|
2月前
|
存储 安全 Linux
如何在 CentOS VPS 上配置 vsftpd 使用 SSL/TLS
如何在 CentOS VPS 上配置 vsftpd 使用 SSL/TLS
30 0
|
3月前
|
Linux 网络安全 开发者
【Python】已解决:WARNING: pip is configured with locations that require TLS/SSL, however the ssl module i
【Python】已解决:WARNING: pip is configured with locations that require TLS/SSL, however the ssl module i
285 3
|
4月前
|
网络安全 安全 Java
Java一分钟之-SSL/TLS:安全套接字层与传输层安全
【6月更文挑战第2天】本文介绍了SSL/TLS协议在保护数据传输中的作用,以及Java中使用JSSE实现SSL/TLS的基础。内容涵盖SSL/TLS工作流程、版本、常见问题及解决办法。通过`SSLSocket`和`SSLServerSocket`示例展示了服务器和客户端的实现,并强调证书管理、配置检查和依赖更新的最佳实践,以确保安全的通信。
330 4