CVE-2014-0160上周在互联网上掀起一股腥风血雨,包括淘宝,支付宝,雅虎,BTCchina,Okcoin,QQ邮箱,微信网页版,微信公众号,知乎,陌陌,12306,网易126,网易163等国内站点都受到影响。

 

 

 

在CVE平台上对漏洞的描述是:OpenSSL 1.0.1g之前的版本,对TLS和DTLS的实现代码中没有正确处理心跳拓展包,导致内存中未处理的敏感数据包可以被攻击者远程获取,读取密钥和64K的内存。媒体炒作的来势汹汹,但小编认为其危害性并没有媒体宣传的那么夸张。


Blogger,Tumbtr,Youtube,GoDaddy,Google,Yahoo,Gmail,Dropbox,LastPass

而这其中所谓被“脱裤”的站点并不多,受到影响的厂商也仅有部分用户的密码受到安全威胁。

部分安全厂商为了谋求自己的利益和营造影响力,展开了捉襟见肘的博弈,例如:

360率先全面防御,360首推修复方案,腾讯电脑管家率先推出修复方案,腾讯联合安全联盟上线OpenSSL漏洞预警,金山安全中心研究OpenSSL漏洞致电脑手机隐私被窃,OpenSSL曝“毁灭性”漏洞百度加速乐率先防御。

其实小编想说,彭博社(Bloomberg)爆出美国NSA早在2012年就已经掌握这个漏洞并利用,媒体和安全厂商一联合,漏洞就炒作起来了。

小编指向说一句:OpenSSL求不黑,安全厂商能够提供修复方案和防护这是最起码应该做到的,否则凭什么叫安全厂商,值得炫耀的是你能够更早的发现这个漏洞,而不是马后炮。如果要说影响范围,我们不妨来看一下Struts2的S016的漏洞影响范围吧。

小编节选习科对Struts2漏洞调研的一部分给大家吧。这部分是Struts2漏洞对银行和金融行业的影响。

Bank of America:服务器基于Struts2框架修改,做了防XSS处理,敏感符号不能提交,但是可以执行命令和备份数据库,不完全统计2E+数据

State Bank of India:手机电子银行版完全不设防,有硬防限制每日流量,数据统计为1E9000W,用户操作记录为100E+

Standard Chartered Bank:渣打银行伦敦,不完全统计数据量约2118W

Альфа-Банк:白俄罗斯阿尔法银行,可进入Windows域,不完全统计数据量1000W+

Norea Bank AB:北欧联行斯德哥尔摩中心,Windows域管理,完整数据数据量不明

石嘴山银行:主站导航系统托管服务器,被挂马,用户数据库应该未受影响,被植后门用户总数不明

第一銀行First Bank:台湾第一银行,泄露数据量不完全统计约1000W

还有各种社交站,服务站,商业站等等,so......

小编就不贴了~象征性的分析下OpenSSL的漏洞吧。

SSL协议全名Secure Socket Leyer,用于提供安全的交互。一般而言以HTTPS开头的URL都是使用了SSL保护。另外SSL也广泛在许多的应用中使用,像IRC也使用SSL协议。

类似于Diffie-Hellman,SSL在连接建立的时候需要服务端和客户端进行交互来协商公钥等。而HeartBeat正是在这样一个过程中起到了'Keep-Alive'的作用。客户端在一定时间内向服务端发送HeartBeat包来显示自己的连接仍然存活,这样就可以避免每一次链接的时候要重新协商公钥,保证了连接的效率。

那么CVE平台中所提及的TLS又是什么?TLS是SSL的一种传输方式,较之于传统SSL更为安全更为广泛使用的一种传输方式。了解了这些,我们不妨来看一看漏洞的成因。

在CVE平台中描述的漏洞相关的文件是d1_both.c和t1_lib.c 。在这里要说明d1_both和t1_lib的区别,t1_lib.c中所蕴含的函数是tls1_process_heartbeat ,是TLS。而在d1_both文件中的函数是dtls1_process_heartbeat,他们极其类似,而dtls1_process_heartbeat确实基于UDP实现的TLS,也就是DTLS,也就是在CVE中提到的另一个存在漏洞的传输方式。

既然如此,我们就先打开t1_lib.c看看漏洞的原因。

#ifndef OPENSSL_NO_HEARTBEATS
int
tls1_process_heartbeat(SSL *s)
{
 unsigned char *p = &s->s3->rrec.data[0], *pl;
 unsigned short hbtype;
 unsigned int payload;
 unsigned int padding = 16; /* Use minimum padding */
 /* Read type and payload length first */
 hbtype = *p++;
 n2s(p, payload);
 pl = p;
代码的2480开始定义了tls1_process_heartbeat函数。在代码中,可以看到是取出了p的第一个字节的内容作为心跳包的类型。而宏n2s取出两字节作为Payload。之后就是发送了。

问题发生在2508行

buffer = OPENSSL_malloc(1 + 2 + payload + padding);
在这里的内存分配,包括前面的赋值都没有对长度做任何的检查,而这里的payload又是可控的,所以导致了Openssl服务可以读取任意的内存位置。

也就是说,攻击者可以通过控制心跳包的大小,让他变得超出预期的大,然后发送到目标服务器的443端口,就可以得到一个64K的包,其中包含的便是边界外,本来不应该被访问到的内存。只要我们写个脚本重复的发送这样的心跳包,便可以重复得到泄露的数据。而且这样的读取方式根本不会在服务器上留下任何的痕迹,也就是说完全无法发现攻击者的IP分析完TLS,去看DTLS发现也是大同小异的实现问题。

 

 

让大家蛋疼的是这段代码代码风格实在是糟糕……变量名各种p啊pl啊bp啊,很难一眼看出他们的意思,小编觉得可读性略差。而这样差可读性的代码,在对指针这么蛋疼的东西进行操作的时候,居然只是出现了这一处的审核不严,附近的代码居然没有任何的漏洞,作者还是比较让人敬佩的。

//silic.wiki