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 已修复该漏洞 ,以及g以上估计也修复了
OpenSSL 1.0.0 分支版本不受此漏洞影响
OpenSSL 0.9.8 分支版本不受此漏洞影响 ///汉澳sinox系统使用的openssl版本
OpenSSL 1.0.2 Beta2 不受此漏洞影响
root@www:~ # openssl version
OpenSSL 0.9.8y 5 Feb 2013
但是如果用户升级到OpenSSL 1.0.1 到 OpenSSL 1.0.1f,就会面临漏洞攻击。用户编译安装定义了OPENSSL_NO_HEARTBEATS,也可以避开此漏洞。引入心跳这个功能应该是为了保持客户端与服务器的连接,其实这个不是必须的。
#ifndef OPENSSL_NO_HEARTBEATS
int
dtls1_process_heartbeat(SSL *s)
{
unsigned char *p = &s->s3->rrec.data[0], *pl;
//rrec是心跳包ssl3结构,用户发来的数据包
/×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;
*/
unsigned short hbtype;
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */
if (s->msg_callback)
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
&s->s3->rrec.data[0], s->s3->rrec.length,
s, s->msg_callback_arg);
/* Read type and payload length first */
if (1 + 2 + 16 > s->s3->rrec.length) //patch
return 0; /* silently discard */ //patch
//这个是补丁,长度为0的心跳包,就返回不要处理
hbtype = *p++;//执行后就是心跳包用户设置的payload,用户可以任意设置
n2s(p, payload);//宏n2s从指针p指向的数组中取出前两个字节,并把它们存入变量payload中,p是客户端的数据,可以设置0xFFFF,最大65535
if (1 + 2 + payload + 16 > s->s3->rrec.length) //patch
return 0; /* silently discard per RFC 6520 sec. 4 */ //patch
//这个是补丁,用户设置payload长度+19超过心跳包实际长度,就返回不要处理
pl = p;
if (hbtype == TLS1_HB_REQUEST)
{
unsigned char *buffer, *bp;
unsigned int write_length = 1 /* heartbeat type */ +
2 /* heartbeat length */ +
payload + padding;
int r;
if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
return 0;
/* Allocate memory for the response, size is 1 byte
* message type, plus 2 bytes payload length, plus
* payload, plus padding
*/
buffer = OPENSSL_malloc(write_length);
bp = buffer;
/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);//宏s2n与宏n2s干的事情正好相反:s2n读入一个16 bit长的值,然后将它存成双字节值,所以s2n会将与请求的心跳包载荷长度相同的长度值存入变量payload
memcpy(bp, pl, payload);
//如果用户并没有在心跳包中提供足够多的数据,会导致什么问题?比如pl指向的数据实际上只有一个字节,那么memcpy会把这条SSLv3记录之后的数据——无论那些数据是什么——都复制出来。后面那些数据可能存有其他用户的密钥,用户名和密码。
这个就是c语言的内存指针,编写者没有考虑到payload会超过数据实际长度的情况,要检查才行。
很幸运,汉澳sinox没有碰上这个漏洞。这是程序设计者增加新功能引入的新漏洞。而bash漏洞则是很久就有的一直没有被发现。所以新版本不意味就更好,因为没有充分测试修复可能产生的新bug.