发布时间:2014-07-15 11:50:28作者:知识屋
4月7日曝光的 Heartbleed 漏洞(编号CVE-2014-0160)已经在相关的 IT 领域(尤其是信息安全领域)造成很大的风波。在安全圈混了十多年,不写点啥有些说不过去。所以今天就这个话题,谈谈俺个人的观点,并给普通用户、程序员、开源社区、安全从业人员 分别提点建议。
这个 Heartbleed,直译成中文就是“心脏出血”。听上去挺吓人滴,现实中也确实挺吓人滴。简而言之,这个漏洞足以载入史册。这几天,大伙儿正在经历信息安全历史上的一个重要时刻。或许你应该觉得荣幸 :)
关于这个漏洞的描述,请看中文维基百科的“ 这里 ”,俺就不浪费口水了。
先发一通抱怨。不喜欢听俺抱怨的,请直接略过。
对整个安全行业而言,这是巨大的耻辱。
OpenSSL 是安全行业内应用非常广泛的开源加密库。一个用来保护安全的软件包,本身居然出现如此严重的漏洞(导致内存信息泄漏),实在太讽刺了。
耻辱的还不光是 OpenSSL——就在一个月之前,GnuTLS 同样出现过高危漏洞(编号CVE-2014-0092)。这么短的时间之内,涉及到加密的两个最常用的基础库接连爆出高危漏洞,俺不禁要问:整个安全行业的面子要往哪儿搁?
对整个开源社区而言,这是巨大的耻辱。
OpenSSL 作为非常知名的开源项目之一,这么严重的漏洞居然两年后才曝光(2012年3月的稳定版就已经包含此漏洞)。难道关键模块的代码变更之后不进行【Code Review】?亦或是 Code Review 只是走过场?
该漏洞曝光前后,风险是不同滴。以下俺分别介绍。
下面会涉及两个术语——“未公开漏洞”和“零日漏洞”——两者的区别请看俺之前的博文。
目前已经有报道指出,在4月7日之前,这个漏洞就已经被骇客利用(报道在“ 这里”)。另外,圈内也有小道消息流传,说某些攻击者早已拿到此漏洞并加以利用。
在这个阶段,知道漏洞的人很少。这时候,该漏洞属于“宝贵资源”,掌握它的人只会拿来攻击“高价值目标”。所以,如果你只是一个普通网友,或者只是一个小型网站,通常不用担心这个阶段的风险。
4月7日那天,OpenSSL 发布了公告。发现漏洞的 CloudFlare 公司也发布了公告。于是这个漏洞瞬间传遍全球。几小时之内,大量的攻击工具应运而生(这个漏洞太容易利用了)。然后大量的“脚本小子”(洋文叫 script kiddie)就拿着这些别人写好的工具,对大量的网站进行扫描。
由于时差的关系,以及某些大公司的官僚风气,很多网站来不及在第一时间升级 OpenSSL 这个软件包(这就是所谓的“零日风险”)。估计某些效率低下的公司,甚至到今天都还没升级。
(本节聊的是该漏洞在技术层面的细节。对 C 语言了解不多的同学,请自行略过,以免浪费时间)
这个漏洞从本质上讲,就是“缓冲区溢出(buffer overflow)”。几乎所有这类漏洞的根源,都是由于程序员的疏忽——对缓冲区涉及的相关“长度”没有仔细检查。
已经有老外写了详细的 Heartbleed 漏洞分析文档(洋文在“ 这里 ”)。对于懒得看长篇的同学,俺把精华摘录如下:
问题出在 OpenSSL 中的 ssl/d1_both.c 文件中的 dtls1_process_heartbeat 函数(看名称就知道该函数是干啥滴)。相关代码有如下(俺补了中文注释)
int dtls1_process_heartbeat(SSL *s) { unsigned char *p = &s->s3->rrec.data[0], *pl; //p 指向对端发来的心跳数据包 unsigned short hbtype; unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ ...... hbtype = *p++; //心跳数据包的第0个字节,表示心跳包的类型 n2s(p, payload); //接下来2个字节是长度。n2s 是个宏,把这2个字节取出,保存为整型,然后指针移2字节 pl = p; //此时p指向第3个字节——也就是对端提供的心跳包载荷 ...... unsigned char *buffer, *bp; int r; buffer = OPENSSL_malloc(1 + 2 + payload + padding); //根据 payload 分配内存,额外的3字节用于存放类型和长度 bp = buffer; ...... *bp++ = TLS1_HB_RESPONSE; //填充类型 s2n(payload, bp); //填充长度 memcpy(bp, pl, payload); //填充回应包的载荷【亮点在这里】
如果对端发来的心跳包有猫腻——包长度跟实际载荷不匹配,那么在发送回应包的时候,那句 memcpy 语句就会把心跳包之后的内存区块也一起 copy 进去,然后发给对端。内存信息就泄露了。
搞清楚问题的根源之后,补丁其实很简单——只需加入2个判断语句(寥寥4行代码)。
if (1 + 2 + 16 > s->s3->rrec.length) return 0; //忽略长度为 0 的心跳包 hbtype = *p++; n2s(p, payload); if (1 + 2 + payload + 16 > s->s3->rrec.length) return 0; //忽略长度与载荷不匹配的心跳包 pl = p;
前面的“风险评估”已经分析了——对于普通网友而言,你的风险主要在于“漏洞曝光之后那1-2天”(也就是“0day”导致的风险)。
从4月7日开始的这几天(尤其是4月8日和4月9日),如果你曾经登录过某个重要的帐号,为了以防万一,改一下密码。国内的很多大网站(包括:电子邮件、电子商务、网银、社交网络、等等)都被发现有 Heartbleed 漏洞。
不过值得庆幸的是,Google 应该没事。根据 OpenSSL 官方的公告(链接在“ 这里
刚开博的头一个季度,俺就发过一篇帖子《 架构设计:进程还是线程?是一个问题! 》,其中提到了多进程的若干优点。今天再来老调重弹,说说“多进程”在安全方面的优点。
针对“缓冲区溢出”
绝大多数的“缓冲区溢出攻击”,都只对当前进程有效。如果你的系统切分成若干个进程,一旦不幸碰上这类攻击,顶多只有一个进程出问题——不至于死得太难看。
不少程序员存在一个误解:以为只有 C/C++ 才会存在缓冲区溢出。其实不然。像 Java/Python 之类的,虽然没有原生的指针,虽然语言的虚拟机/解释器本身对缓冲区越界有严格的检查。但是不要忘了:这些语言的虚拟机/解释器本身也是用 C/C++ 来编写的。说不定虚拟机自己就有问题。
针对“信息泄露”
这次的“Heartbleed漏洞”,从技术上讲属于“缓冲区溢出”类型,从逻辑讲属于“信息泄漏”类型。
如果整个系统切分成很多轻量级的进程,每个进程包含的内存信息自然就少了。一旦出现“信息泄漏”的漏洞,损失会小很多。
针对“拒绝服务”
多进程除了可以降低上述两类的受伤程度,还可以降低“拒绝服务攻击”导致的受伤程度。
比如某些漏洞通过让“进程崩溃”来起到“拒绝服务”的效果。如果系统的架构是多进程的,并且相关进程具有一定的自我恢复机制,那么就可以降低这类攻击造成的伤害程度。
如今比较成熟的网站,应该不会采用“明文”的方式存储用户密码了。很多程序员/架构师都明白,要把用户密码进行散列(Hash)之后再存储。但是这里面有一个细节,很多人忽略了。那就是:“服务端散列”vs“客户端散列”?
所谓的“服务端散列”就是:用户输入密码之后,以明文的方式传送到服务端,然后在服务端进行散列,散列的结果保存到数据库。
所谓的“客户端散列”就是:用户输入密码之后,现在浏览器这端用 JavaScript 计算散列值,然后把算好的散列值传送到服务端,再保存到数据库。
到目前为止,大多数网站(包括很多大型网站)还是采用服务端散列。其实捏,“客户端散列”比“服务器散列”的安全性更好。为啥捏?
对于成熟的大型网站,虽然用户登录过程都是基于加密 HTTPS 传输。但是 HTTPS 不是绝对安全的。俺相信 HTTPS 协议本身的设计是很完备的,但是“协议没问题”不等于“整个HTTPS传输没问题”。整个 HTTPS 传输,可能出问题的环节如下:
1. 软件可能出问题
比如这次的 Heartbleed 漏洞,就属于典型的“基础软件库出问题”
先声明:“黑客”与“骇客”是完全不同的两类人。俺之前发过一篇《 每周转载:关于黑客文化和黑客精神 》,或许有助于你了解两者的差异。
俺敢跟任何人打赌,OpenSSL 和 GnuTLS 的代码中,类似的低级错误还有好多。而且 GnuTLS 可能比 OpenSSL 还多。有志于成为黑客的同学,可以考虑去分析这俩的代码,找出其中的。
通过上面那段代码分析,你应该会意识到:这个漏洞本身并没有涉及到多么高深的 C 语法或技巧。那么,发现该漏洞的难点在哪里?俺觉得难在:
1. 对整体结构的把握
因为 OpenSSL 和 GnuTLS 的代码量还是比较庞大的。很少有人能把握整体的结构。
2. 对相关协议的了解
想通过看代码分析这两个软件的漏洞,你还需要对相关的协议很熟悉。比如这次的漏洞,就涉及到“心跳协议”的细节。
3. 耐心/恒心
同时具备上述两条的人本来就不多。然后捏,这些人还未必有足够的耐心去把整个代码(哪怕是其中某个模块的代码)通读一遍。
(第三点或许才是最难的)
如果能够搞定上述三点,并且你的运气足够好,那么你有望独立发现一个高危漏洞。
2011-06-17
电脑开机时出现lass.exe进程是病毒吗?
自拍须谨慎!教你如何通过照片定位查看拍摄地点
电脑病毒最基础知识
黑客学员必须了解的C语言技术
精典详细内网渗透专题文章
教你破解Tp-Link的无线路由密码
解决SecureCRT中文显示乱码
QQ电脑管家和360哪个好?横评实测对比
攻防实战:无线网络路由入侵过程