CVE-2014-0160-OpenSSL TLS 数组越界访问漏洞(“心脏出血”漏洞)

由于这个是开源的,直接源码对比
https://bugzilla.redhat.com/attachment.cgi?id=883475&action=diff

修复的另外一处也差不多

两处都对s->s3->rrec.length进行了判断

这个rrec结构如下:

1
2
3
4
5
6
7
8
9
10
11
typedef struct ssl3_record_st
{
/*r */ int type; /* type of record */
/*rw*/ unsigned int length; /* How many bytes available */
/*r */ unsigned int off; /* read/write offset into 'buf' */
/*rw*/ unsigned char *data; /* pointer to the record data */
/*rw*/ unsigned char *input; /* where the decode bytes are */
/*r */ unsigned char *comp; /* only used with decompression - malloc()ed */
/*r */ unsigned long epoch; /* epoch number, needed by DTLS1 */
/*r */ unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
} SSL3_RECORD;

length(心跳包的长度)是用户可控的,而payload(也是储存长度)是也是用户可控的,那么当payload长度大于心跳包的长度,那么就可以读取内存中心跳包后面的数据了

我们看看泄露这一步,首先是是malloc的大小,复制的大小都是payload这个变量

1
2
3
4
5
6
7
8
9
10
11
12
buffer = OPENSSL_malloc(1 + 2 + payload + padding);   //分配内存
bp = buffer; //buffer即bp

/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload); //复制到bp
bp += payload;
/* Random padding */
RAND_pseudo_bytes(bp, padding);

r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); //将前面复制到bp的数据,写到s结构的特定变量返回到用户(因为buffer就是bp)

那么这个就可以越界读取内存的信息,可能读取到密码什么的

再说说SSL3_RT_MAX_PLAIN_LENGTH那个,SSL3_RT_MAX_PLAIN_LENGTH在源码中找到是16384,所以这里的判断应该不是最重点,这个限制了最大长度

1
#define SSL3_RT_MAX_PLAIN_LENGTH		16384
自愿打赏专区