前段时间写的漏洞的分析报告贴上来~
OpenSSlHeartBleed 漏洞分析及验证
一.漏洞爆出
OpenSSL是一个使用非常广泛的开源加密库,用来实现网络通信的加密。本次爆出的OpenSSL 是TLS心跳造成远程信息泄露漏洞 (CVE-2014-0160)
在处理TLS心跳扩展中缺失了边界检查,可导致服务器端64K内存信息的泄露
影响版本:OpenSSL Project OpenSSL 1.0.2-beta
OpenSSL Project OpenSSL 1.0.1
漏洞公布的信息
http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html
二.漏洞成因
TLS心跳延长首次记载是在RFC6520,心跳被用作“保持活动”的数据包,这样的加密连接的两端都同意保持会话打开,即使他们没有交换任何官方数据。因为心跳由一个答复,并匹配响应,不仅使会话是确认开放的,也表明终端对终端的连接是否正常工作
上面这个链接是漏洞发现者的分析,我们这里简要说明下这个漏洞的成因
心跳请求:
OpenSSL heartbeat request code looks like this:
unsigned int payload = 18; /* Sequencenumber + random bytes */
unsigned int padding = 16; /* Use minimumpadding */
/* Check if padding is too long, payloadand padding
* must not exceed 2^14 - 3 = 16381 bytes intotal.
*本人注:在RFC6520中要求心跳最大尺寸为2^14(16K)个字节
*其实这个地方通过发送心跳的包来看,这个地方限制在了14个字节
*其他三个字节分别为1个字节心跳请求信号TLS1_HB_REQUEST和2个字节的请求中指明的payload长度,也就是这个地方出现了bug,我们继续分析
*p.s这个漏洞一直说可以可以dump64K的内存处理,但是修改攻击代码,还是只能取得16K,*可能就跟这个地方有关系
*/
OPENSSL_assert(payload + padding <=16381);
/* Create HeartBeat message, we just use asequence number
* as payload to distuingish differentmessages and add
* some random stuff.
* - Message Type, 1 byte
* - Payload Length, 2 bytes(unsigned int)
* - Payload, the sequencenumber (2 bytes uint)
* - Payload, random bytes (16bytes uint)
* - Padding
*/
buf = OPENSSL_malloc(1 + 2 + payload +padding);
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
/* Payload length (18 bytes here) */
s2n(payload, p);
/* Sequence number */
s2n(s->tlsext_hb_seq, p);
/* 16 random bytes */
RAND_pseudo_bytes(p, 16);
p += 16;
/* Random padding */
RAND_pseudo_bytes(p, padding);
ret = dtls1_write_bytes(s,TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
该代码然后发送包括心跳的标准请求:
· 单字节0x01(表示这是一个TLS1_HB_REQUEST)。
· payload大小,两个字节
· payload的序列号,两个字节
· payload中的随机字节,16个字节
· padding,16个字节的随机填充字符
这里我们可以根据攻击POC中直观的看到定义的这种心跳数据结构,构造的包为
hb=h2bin('''1803020003014000''')
其中0x18 0x03 0x02为TLS1.1版本的版本信息,0x00 0x03 为心跳包请求的长度,0x01即为TLS1_HB_REQUEST,0x40 0x00即为payload的长度,这个是可修改的,这个POC没有随机字符和padding,所以请求包长度为3个字节,网络包大字节序
回复心跳请求
当OpenSSL的1.0.1版本,在处理接收到的心跳数据时,
/* Enter response type, length and copypayload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);
心跳答复都应该包含来自请求的有效载荷数据的副本,这里通过memcpy直接将pl指向的地址数据中,将具有payload长度的数据回复给请求端,没有进行payload长度的验证,也就是说你可以发送一个小的心跳请求,但你偷偷有效载荷长度字段设置为0xFFFF(65535字节)。然后,OpenSSL的将毫无怨言地从你的请求数据包复制65535字节,即使你没有送跨越很多字节,这意味着给OpenSSL发送一个畸形的心跳请求,则会将64K的内存数据泄露。
三.漏洞验证
我们这里采用攻击POC进行验证分析(不公布测试POC,网上流传着很多版本,但是注意各利用里内容,小心直接弄个反弹就不好了)
我们只进行测试性验证,比如某云服务(好像图贴不过来了啊,那就算了)
我们从中看到了uername,password,经过验证时可以登录成功的
我们看另外一个验证结果,是一款聊天通信软件,我们看看测试结果
收集到的信息包括用户名,密码,还有登陆的其他信息等等,尽管这个密码是MD5加密的,但是md5加密的结果还是部分能够解开的,所以危害同样巨大
四. 漏洞危害
该漏洞利用的成本低,可以一直这么dump内存出来,尽管里边包含了很多无用和截断信息,但是还是可以收集到很多隐私信息的,比如私钥,用户名,密码,cookie等等
淘宝,yahoo,12306等等网站,好多都存在这种问题,而且危害被逐渐挖掘出来,比如服务端和客户端对打~
五. 建议
1. 立即更新补丁
OpenSSL Project已经为此发布了一个安全公告(secadv_20140407)以及相应补丁
2.比如在IPS设备上检测这种漏洞可以用请求包的长度和次数做检测
Since OpenSSL uses hardcoded values thatnormally result in a 61 byte heartbeat message size
比如可以参考:alert tcp $EXTERNAL_NET any -> $HOME_NET 443(msg:"SERVER-OTHER OpenSSL TLSv1.1 heartbeat read overrun attempt";flow:to_server,established; content:"|18 03 02|"; depth:3;dsize:>40; detection_filter:track by_src, count 3, seconds 1;metadata:policy balanced-ips drop, policy security-ips drop, service ssl;reference:cve,2014-0160; classtype:attempted-recon; sid:30512; rev:2;)
alert tcp $HOME_NET 443 -> $EXTERNAL_NET any (msg:"SERVER-OTHER TLSv1.1large heartbeat response - possible ssl heartbleed attempt";flow:to_client,established; content:"|18 03 02|"; depth:3;byte_test:2,>,128,0,relative; detection_filter:track by_dst, count 5,seconds 60; metadata:policy balanced-ips drop, policy security-ips drop,service ssl; reference:cve,2014-0160; classtype:attempted-recon; sid:30516;rev:3;)
端口并不要一定要限定在443,比如POP3收邮件就是POP3 SSL 995端口
后来又出来一种基于SSL加密管道下,然后再进行heartbleed打的情况,这种情况,一般IPS是很难搞定的
3.最近如果登陆过这些网站,注意修改密码