OpenSSL SSL_get_shared_ciphers() off-by-one buffer overflow

系统错误报告和讨论
回复
westhack
帖子: 2
注册时间: 2007-09-26 0:58
送出感谢: 0
接收感谢: 0

OpenSSL SSL_get_shared_ciphers() off-by-one buffer overflow

#1

帖子 westhack » 2007-09-30 14:28

Bugtraq ID: 25831
Class: Boundary Condition Error
CVE: CVE-2007-5135

Remote: Yes
Local: No
Published: Sep 27 2007 12:00AM
Updated: Sep 29 2007 06:09PM
Credit: Moritz Jodeit <moritz@jodeit.org> discovered this issue.
Vulnerable: Ubuntu Ubuntu Linux 7.04 sparc
Ubuntu Ubuntu Linux 7.04 powerpc
Ubuntu Ubuntu Linux 7.04 i386
Ubuntu Ubuntu Linux 7.04 amd64
Ubuntu Ubuntu Linux 6.10 sparc
Ubuntu Ubuntu Linux 6.10 powerpc
Ubuntu Ubuntu Linux 6.10 i386
Ubuntu Ubuntu Linux 6.10 amd64
Ubuntu Ubuntu Linux 6.06 LTS sparc
Ubuntu Ubuntu Linux 6.06 LTS powerpc
Ubuntu Ubuntu Linux 6.06 LTS i386
Ubuntu Ubuntu Linux 6.06 LTS amd64
OpenSSL Project OpenSSL 0.9.8 e
OpenSSL Project OpenSSL 0.9.8 d
OpenSSL Project OpenSSL 0.9.7 m
OpenSSL Project OpenSSL 0.9.7 l



OpenSSL SSL_get_shared_ciphers() off-by-one buffer overflow

Copyright (c) 2007 Moritz Jodeit <moritz (at) jodeit (dot) org [email concealed]> (2007/09/27)
-----------------------------------------------------------------

Application details:

OpenSSL is a widely used open source implementation of the
SSL v2/v3 and TLS v1 protocols.

Vulnerability description:

OpenSSL 0.9.7l and 0.9.8d fixed a buffer overflow found in
the SSL_get_shared_ciphers() function reported by Tavis
Ormandy and Will Drewry of the Google Security Team.

Although this fix prevented the unlimited overflow of the
buffer, it still allowed an off-by-one buffer overflow to
happen, which could potentially still result in remote code
execution.

Here is an excerpt of the function from ssl/ssl_lib.c:

p=buf;
sk=s->session->ciphers;
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
/* Decrement for either the ':' or a '\0' */
len--; [4]
c=sk_SSL_CIPHER_value(sk,i);
for (cp=c->name; *cp; )
{
if (len-- <= 0) [1]
{
*p='\0'; [5]
return(buf);
}
else
*(p++)= *(cp++); [2]
}
*(p++)=':'; [3]
}
p[-1]='\0';
return(buf);

The old vulnerability got fixed at [1] by comparing 'len'
against <= 0 instead of == 0 to detect the possible
underflow of 'len'.

To trigger the off-by-one, you'd just fill the buffer
with cipher strings up to the point, where 'len' == 1 and
'cp' pointing to the last character of the current cipher
string. The last round of the inner for() loop would then
decrement 'len' to 0 at [1] and write the last byte of the
current cipher string into the buffer [2], increasing 'p'
to point to the last free byte of the buffer.
The last free byte is then filled by the ':' separator and
'p' is increased to point one byte behind the buffer.
Now if there are still ciphers remaining, we enter the
outer loop again, decrease 'len' to -1 at [4] and then
hit the check at [1] again. This time it's true and the
terminating '\0' byte is written one byte behind the
buffer [5] before returning.

Vendor response:

2007/06/06 Initial contact with openssl-security (at) openssl (dot) org [email concealed]
2007/07/06 Response received by Ben Laurie <ben (at) links (dot) org [email concealed]>
regarding a proposed fix.
2007/09/19 Fix committed to the OpenSSL_0_9_8-stable branch
in CVS.

Vulnerable packages:

All applications using the SSL_get_shared_ciphers() function from
the OpenSSL library up to 0.9.7m and 0.9.8e.
回复

回到 “Ubuntu错误报告”