苹果 SSL/TLS Bug的细节

简介:
+关注继续查看

近日,苹果向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/

相关文章
|
4月前
|
安全 前端开发 JavaScript
斐迅面试记录—SSL和TLS的区别
斐迅面试记录—SSL和TLS的区别
52 0
|
9月前
|
安全 Linux 网络安全
CentOS7下vsftpd over SSL/TLS加密传输配置实践
CentOS7下vsftpd over SSL/TLS加密传输配置实践
286 0
CentOS7下vsftpd over SSL/TLS加密传输配置实践
|
10月前
|
存储 缓存 JavaScript
【Node.js 】开发中遇到的多进程‘keylog‘ 事件以及TLS/SSL的解决学习方案实战
【Node.js 】开发中遇到的多进程‘keylog‘ 事件以及TLS/SSL的解决学习方案实战
【Node.js 】开发中遇到的多进程‘keylog‘ 事件以及TLS/SSL的解决学习方案实战
|
11月前
|
安全 算法 网络安全
网络和通信安全中的SSL / TLS国密改造
GB/T39786提供了信息系统密码应用的技术框架,互联网、政务外网、企业专网等网络类型,涉及通信主体的各个要素,都需要遵循要求进行改造升级。
2094 0
网络和通信安全中的SSL / TLS国密改造
|
11月前
|
自然语言处理 算法 网络协议
SSL和TLS协议如何提供身份验证、机密性和完整性
SSL 和 TLS 协议使两方能够相互识别和验证,并以机密性和数据完整性进行通信。
233 0
SSL和TLS协议如何提供身份验证、机密性和完整性
|
11月前
|
Web App开发 移动开发 安全
[ 网络协议篇 ] 一篇文章让你掌握什么是 数字证书 ?什么是SSL ?什么是 TLS ?(下)
[ 网络协议篇 ] 一篇文章让你掌握什么是 数字证书 ?什么是SSL ?什么是 TLS ?(下)
116 0
[ 网络协议篇 ] 一篇文章让你掌握什么是 数字证书 ?什么是SSL ?什么是 TLS ?(下)
|
11月前
|
运维 安全 网络安全
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
485 0
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
|
运维 安全 算法
金鱼哥RHCA回忆录:DO447Ansible Tower的维护和常规管理--配置TLS/SSL
第十四章 Ansible Tower的维护和常规管理--配置TLS/SSL
118 0
金鱼哥RHCA回忆录:DO447Ansible Tower的维护和常规管理--配置TLS/SSL
|
Web App开发 数据采集 存储
HTTPS与HTTP的区别?(什么是SSL和TLS?)
HTTPS与HTTP的区别?什么是SSL和TLS?(https://www.o0310o.com/kb/425.html)HTTP:超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议。为了增加安全性,HTTPS 横空出世 网景(曾经很强大的收费浏览器公司,后来被微软用免费的IE搞死)在 1994 年创建了 HTTPS,并应用在网景导航者浏览器中。
237 0
HTTPS与HTTP的区别?(什么是SSL和TLS?)
EMQ
|
负载均衡 安全 算法
车联网通信安全之 SSL/TLS 协议
本篇文章我们将全面介绍 SSL/TLS 协议在车联网通信安全中的应用,并详细讲解 SSL/TLS 的配置方式。
EMQ
283 0
车联网通信安全之 SSL/TLS 协议