作者:申迪
继HeartBleed之后,OpenSSL于6月5日再度公开了六个安全漏洞。其中‘Early CCS’ (CVE-2014-0224)可被用于中间人攻击,窃听通信数据。而CVE-2014-0195则是一个堆溢出漏洞,客户端和服务端均可被攻击,理论上存在远程代码执行的可能性。另外四个则可被用于DoS(Denial of Service,拒绝服务)攻击。
‘Early CCS’是指在SSL握手过程中,提前发送ChangeCipherSpec信号的攻击方式。互联网工程任务组(IETF)的RFC5246中对握手协议部分的表述如下:
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
Figure 1. Message flow for a full handshake
握手协议作为SSL的一个子协议,在实现过程中是一个状态机。但握手协议中ChangeCipherSpec(更改密钥规格)并不是一个握手消息,而是一个独立的TLS子协议类型。对此做法的官方解释是为了避免流水线推迟。该漏洞的发现者Masashi Kikuchi认为这种设计是漏洞成因之一。
在整个握手协议中,也没有强制对ChangeCipherSpec的发送顺序做任何校验,那么中间人攻击者有机会在握手过程中的任何时机插入ChangeCipherSpec消息。一种可能的攻击方法就是,在计算出master、生成对称密钥之前,就插入ChangeCipherSpec消息。这将导致消息接收方以全空的master生成对称密钥。那么中间人有机会完全窃听通信过程中的加密数据。
该漏洞已经存在长达15年之久。所有客户端版本都受该漏洞的影响,1.0.1 和 1.0.2-beta1的服务端收到了影响。该漏洞攻击必须是在客户端和服务端均未打补丁的条件下成立。
安卓客户端同样受到了影响,AOSP在第一时间修复了该漏洞,代码已经提交到主分支。建议所有手机厂商都及时跟进这个修复。
对于服务端,Google的Adam Langley提供了一份go语言的测试工具,可以快速检测服务端是否存在Early CCS漏洞。
而CVE-2014-0195则是对DTLS数据包格式合法性校验不全导致的。该漏洞由HP的Jüri Aedla发现并提交跟官方。DTLS是TLS的UDP版本,当数据过大时,DTLS将消息切分为多个fragment,并认为这几个fragment的长度是一致的。
但是代码中对这种一致性没有做任何校验,那么我们构造一组长度不一致的包也会被接收。
图片引自HP Security Research Blog
static int dtls1_reassemble_fragment(SSL s, struct hm_header_st msg_hdr, int *ok) { item = pqueue_find(s->d1->buffered_messages, seq64be);
if (item == NULL)
{
//关键代码:分配内存
frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
if ( frag == NULL)
goto err;
memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
frag->msg_header.frag_len = frag->msg_header.msg_len;
frag->msg_header.frag_off = 0;
}
else
frag = (hm_fragment*) item->data;
代码在解析fragment时认为,所有的fragment大小都是一致的,所以每一次调用dtls1_hm_fragment_new是都使用了msg_hdr->msglen,即第一个fragment的长度来分配内存。但是第二个fragment是畸形超长的,所以会有987个字节被拷贝到2字节的内存块上,造成内存破坏。
最新的代码上已经添加了校验,检查每一个fragment的长度是否和第一个一致。
@@ -632,7 +632,16 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
frag->msg_header.frag_off = 0;
}
else
+ {
frag = (hm_fragment*) item->data;
+ if (frag->msg_header.msg_len != msg_hdr->msg_len)
+ {
+ item = NULL;
+ frag = NULL;
+ goto err;
+ }
+ }
+
目前AOSP上还没有对该漏洞进行修复,手机厂商可以参考OpenSSL的补丁进行修复。
一些研究人员认为,OpenSSL存在着的一些逻辑漏洞,是由于代码review不足所导致的。HeartBleed漏洞的曝光,使更多人投入到OpenSSL的review和fuzzing当中去,特别是研究Robin Seggelmann(HeartBleed漏洞代码的提交者)的代码。几个漏洞的修补,并不代表这个模块就安全了,可能是意味着该模块存在着更多的隐患。我们会对OpenSSL安全问题保持持续关注。
参考资料:
OpenSSL Security Advisory [05 Jun 2014]
https://www.openssl.org/news/secadv_20140605.txt
IETF RFC 5246
http://tools.ietf.org/html/rfc5246#section-7.3
How I discovered CCS Injection Vulnerability (CVE-2014-0224), Masashi Kikuchi
http://ccsinjection.lepidum.co.jp/blog/2014-06-05/CCS-Injection-en/index.html
Early ChangeCipherSpec Attack, Adam Langley
https://www.imperialviolet.org/2014/06/05/earlyccs.html
ZDI-14-173/CVE-2014-0195 – OpenSSL DTLS Fragment Out-of-Bounds Write: Breaking up is hard to do,HP Security Research Blog
AOSP Review
https://android-review.googlesource.com/#/c/96707/
Github: Fix for CVE-2014-0224
https://github.com/openssl/openssl/commit/a91be10833e61bcdc9002de28489405101c52650
Github: Fix for CVE-2014-0195
https://github.com/openssl/openssl/commit/410e444b71bca5af929fe82162cbe37e31c82083
深入研究SSL
http://blog.163.com/hao_dsliu/blog/static/13157890820111112874930/
CVE-2014-0195 openssl: Buffer overflow via DTLS invalid fragment,Red Hat Bugzilla
Comments