06月09, 2014

OpenSSL六漏洞再公开,安卓客户端受影响

作者:申迪

继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的长度是一致的。

但是代码中对这种一致性没有做任何校验,那么我们构造一组长度不一致的包也会被接收。

original

图片引自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

http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/ZDI-14-173-CVE-2014-0195-OpenSSL-DTLS-Fragment-Out-of-Bounds/ba-p/6501002#.U5Us3j-Sxn9

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

https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-0195

本文链接:https://blogs.360.net/post/openssl-bugs-06-05.html

-- EOF --

Comments