OpenSSL “asn1_d2i_read_bio()” DER格式数据处理漏洞

受影响系统:

OpenSSL Project OpenSSL 1.x
OpenSSL Project OpenSSL 0.x

不受影响系统:

OpenSSL Project OpenSSL 1.0.1a
OpenSSL Project OpenSSL 1.0.0i
OpenSSL Project OpenSSL 0.9.8v

描述:


BUGTRAQ  ID: 53158
CVE ID: CVE-2012-2110

OpenSSL是一种开放源码的SSL实现,用来实现网络通信的高强度加密,现在被广泛地用于各种网络应用程序中。

OpenSSL在处理DER格式数据时, “asn1_d2i_read_bio()”函数中存在类型转换错误,可被利用造成堆缓冲区溢出,导致执行任意代码。成功利用的平台为64位系统。

typedef struct asn1_const_ctx_st
{
    const unsigned char *p;/* work char pointer */
    int eos;    /* end of sequence read for indefinite encoding */
    int error;  /* error code to use when returning an error */
    int inf;    /* constructed if 0x20, indefinite is 0x21 */
    int tag;    /* tag from last 'get object' */
    int xclass; /* class from last 'get object' */
    long slen;  /* length of last 'get object' */
    const unsigned char *max; /* largest value of p allowed */
    const unsigned char *q;/* temporary variable */
    const unsigned char **pp;/* variable */
    int line;   /* used in error processing */
} ASN1_const_CTX;

These members are populated via calls to ASN1_get_object and asn1_get_length
which have the following prototypes

int ASN1_get_object(const unsigned char **pp,
                    long *plength,
                    int *ptag,
                    int *pclass,
                    long omax);

int asn1_get_length(const unsigned char **pp,
                    int *inf,
                    long *rl,
                    int max);

The lengths are always stored as signed longs, however, asn1_d2i_read_bio
casts ASN1_const_CTX->slen to a signed int in multiple locations. This
truncation can result in numerous conversion problems.

The most visible example on x64 is this cast incorrectly interpreting the
result of asn1_get_length.

222             /* suck in c.slen bytes of data */
223             want=(int)c.slen;

A simple way to demonstrate this is to prepare a DER certificate that contains
a length with the 31st bit set, like so

$ dumpasn1 testcase.crt
0 NDEF: [PRIVATE 3] {
   2 2147483648:   [1]
        ...
   }

Breakpoint 2, asn1_d2i_read_bio (in=0x9173a0, pb=0x7fffffffd8f0) at a_d2i_fp.c:224
224             if (want > (len-off))
(gdb) list
219             }
220         else
221             {
222             /* suck in c.slen bytes of data */
223             want=(int)c.slen;
224             if (want > (len-off))
225                 {
226                 want-=(len-off);
227                 if (!BUF_MEM_grow_clean(b,len+want))
228                     {
(gdb) p c.slen
$18 = 2147483648
(gdb) p want
$19 = -2147483648

This results in an inconsistent state, and will lead to memory corruption.

建议:


厂商补丁:

OpenSSL Project
—————
OpenSSL Project已经为此发布了一个安全公告(secadv_20120419)以及相应补丁:

secadv_20120419:OpenSSL Security Advisory [19 Apr 2012]

链接:http://www.openssl.org/news/secadv_20120419.txt

评论关闭。