附近约一泡50元_附近初中生联系方式,全国同城凤凰楼信息茶楼,风楼阁全国资源共享平台

OpenSSL 心血漏洞(Heartbleed)修复方案

概述

OpenSSL?心血(HeartBleed)漏洞?是openssl?在?2014-04-07?公布的重大安全漏洞(CVE-2014-0160)这个漏洞使攻击者能够从服务器内存中读取64 KB的数据,甚至获取到加密流量的密钥,用户的名字和密码,以及访问的内容。

主要影响版本?OpenSSL?1.0.1?到?OpenSSL?1.0.1f ?以及?OpenSSL?1.0.2 Beta1

不受此漏洞影响的?OpenSSL版本信息
OpenSSL?1.0.1g?已修复该漏洞?
OpenSSL?1.0.0?分支版本不受此漏洞影响?
OpenSSL?0.9.8?分支版本不受此漏洞影响?
OpenSSL?1.0.2 Beta2?不受此漏洞影响

?

?

确认站点是否存在此漏洞

1.可以直接利用在线工具检测?https站点是否存在此漏洞(快捷、准确)

http://www.601869.cn/tools/bleed-checker/

?

?

未受此漏洞影响的站点:

?

?

?

受此漏洞影响的站点:?

2.查看提供加密服务的OpenSSL版本是否在受影响的版本范围?( 1.0.1—1.0.1f /?1.0.2 Beta1?)

?

操作系统openssl版本查看:

命令:openssl version

结果:OpenSSL?1.0.0-fips 29 Mar 2010

?

nginx openssl版本查看:

?

命令:?nginx –V

结果:

nginx version: nginx/1.5.13

built by gcc 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)

TLS SNI support enabled

configure arguments: --prefix=/usr/local/nginx-1.5.13 --with-select_module --with-http_ssl_module?--with-openssl=/home/user/openssl-1.0.1g?--with-http_spdy_module --with-pcre=/home/user/pcre-8.33 --with-zlib=/home/user/zlib-1.2.8

?

windows Apache openssl版本查看:

命令:D:\httpd-2.4.7-x64\Apache24\bin>openssl version

结果:

WARNING: can't open config file: /apache24/conf/openssl.cnf

OpenSSL?1.0.1e 11 Feb 2013

?

?

?

修复方案

Openssl:

升级OpenSSL?1.0.1g

?

Nginx:

官方在?2014-04-08?发布了最新版本?1.5.13?修复了此漏洞请升级至最新版本

?

Apache:

建议下载最新版本openssl?和?Apache

重新编译安装。

?

其他受影响的WebServer:

建议到官方更新不受此漏洞影响的版本

?

?

漏洞分析

OpenSSL是Apache和nginx网络服务器的默认安全协议,此外大量操作系统、电子邮件和即时通讯系统也采用OpenSSL加密用户数据?通讯。而此次发现的bug已经存在两年之久,这意味着攻击者可以利用该bug获取大量互联网服务器与用户之间的数字证书私钥,从而获取用户账户密码等敏感?数据。由于攻击者不会在服务器日志中留下痕迹,因此网站系统管理员将无法得知系统漏洞是否已经被黑客利用,也无从得知用户数据和账号是否已经被黑客扫描获

?

OpenSSL已经发布了1.0.1g修正bug,Debian发行版也在半小时修复了bug,Fedora发布了一个权宜的修正方案。?该bug是在2011年引入到OpenSSL中,使用OpenSSL?0.9.8的发行版不受影响,但Debian Wheezy、Ubuntu 12.04.4、?Centos 6.5、Fedora 18、SuSE 12.2、OpenBSD 5.4、FreeBSD 8.4和NetBSD 5.0.2之后的版本都受到影响。如果你运行存在该bug的系统,那么最好废除所有密钥。

?

?

源码分析

原作者:Sean Cassidy?原作者Twitter:@ex509 原作者博客:http://blog.existentialize.com?来源:http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html

0x01 Bug


请看ssl/dl_both.c,漏洞的补丁从这行语句开始:

1

2

3

4

5

6

7

int????????????

dtls1_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 */

一上来我们就拿到了一个指向一条SSLv3记录中数据的指针。结构体SSL3_RECORD的定义如下(译者注:结构体SSL3_RECORD不是SSLv3记录的实际存储格式。一条SSLv3记录所遵循的存储格式请参见下文分析):

1

2

3

4

5

6

7

8

9

10

11

typedef?struct?ssl3_record_st

????{

????????int?type;?????????????? /* type of record */

????????unsigned int?length;????/* How many bytes available */

????????unsigned int?off;?????? /* read/write offset into 'buf' */

????????unsigned char?*data;????/* pointer to the record data */

????????unsigned char?*input;?? /* where the decode bytes are */

????????unsigned char?*comp;????/* only used with decompression - malloc()ed */

????????unsigned long?epoch;????/* epoch number, needed by DTLS1 */

????????unsigned char?seq_num[8]; /* sequence number, needed by DTLS1 */

????} SSL3_RECORD;

每条SSLv3记录中包含一个类型域(type)、一个长度域(length)和一个指向记录数据的指针(data)。我们回头去看dtls1_process_heartbeat:

1

2

3

4

/* Read type and payload length first */

hbtype = *p++;

n2s(p, payload);

pl = p;

SSLv3记录的第一个字节标明了心跳包的类型。宏n2s从指针p指向的数组中取出前两个字节,并把它们存入变量payload中——这实际上是心跳包载荷的长度域(length)。注意程序并没有检查这条SSLv3记录的实际长度。变量pl则指向由访问者提供的心跳包数据。

这个函数的后面进行了以下工作:

1

2

3

4

5

6

7

8

9

unsigned char?*buffer, *bp;

int?r;

?

/* Allocate memory for the response, size is 1 byte

?* message type, plus 2 bytes payload length, plus

?* payload, plus padding

?*/

buffer = OPENSSL_malloc(1 + 2 + payload + padding);

bp = buffer;

所以程序将分配一段由访问者指定大小的内存区域,这段内存区域最大为?(65535 + 1 + 2 + 16)?个字节。变量bp是用来访问这段内存区域的指针。

1

2

3

4

/* Enter response type, length and copy payload */

*bp++ = TLS1_HB_RESPONSE;

s2n(payload, bp);

memcpy(bp, pl, payload);

宏s2n与宏n2s干的事情正好相反:s2n读入一个16 bit长的值,然后将它存成双字节值,所以s2n会将与请求的心跳包载荷长度相同的长度值存入变量payload。然后程序从pl处开始复制payload个字节到新分配的bp数组中——pl指向了用户提供的心跳包数据。最后,程序将所有数据发回给用户。那么Bug在哪里呢?

0x01a?用户可以控制变量payload和pl

如果用户并没有在心跳包中提供足够多的数据,会导致什么问题?比如pl指向的数据实际上只有一个字节,那么memcpy会把这条SSLv3记录之后的数据——无论那些数据是什么——都复制出来。

很明显,SSLv3记录附近有不少东西。

说实话,我对发现了OpenSSL“心脏出血”漏洞的那些人的声明感到吃惊。当我听到他们的声明时,我认为64 KB数据根本不足以推算出像私钥一类的数据。至少在x86上,堆是向高地址增长的,所以我认为对指针pl的读取只能读到新分配的内存区域,例如指针bp指向的区域。存储私钥和其它信息的内存区域的分配早于对指针pl指向的内存区域的分配,所以攻击者是无法读到那些敏感数据的。当然,考虑到现代malloc的各种神奇实现,我的推断并不总是成立的。

当然,你也没办法读取其它进程的数据,所以“重要的商业文档”必须位于当前进程的内存区域中、小于64 KB,并且刚好位于指针pl指向的内存块附近。

研究者声称他们成功恢复了密钥,我希望能看到PoC。如果你找到了PoC,请联系我。

0x01b?漏洞修补

修复代码中最重要的一部分如下:

1

2

3

4

5

6

7

8

/* Read type and payload length first */

if?(1 + 2 + 16 > s->s3->rrec.length)

????return?0; /* silently discard */

hbtype = *p++;

n2s(p, payload);

if?(1 + 2 + payload + 16 > s->s3->rrec.length)

????return?0; /* silently discard per RFC 6520 sec. 4 */

pl = p;

这段代码干了两件事情:首先第一行语句抛弃了长度为0的心跳包,然后第二步检查确保了心跳包足够长。就这么简单。