Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:18089
HistorySep 28, 2007 - 12:00 a.m.

OpenSSL SSL_get_shared_ciphers() off-by-one buffer overflow

2007-09-2800:00:00
vulners.com
17

OpenSSL SSL_get_shared_ciphers() off-by-one buffer overflow

Copyright (c) 2007 Moritz Jodeit <[email protected]> (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&#40;&#41; 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-&gt;session-&gt;ciphers;
    for &#40;i=0; i&lt;sk_SSL_CIPHER_num&#40;sk&#41;; i++&#41;
            {
            /* Decrement for either the &#39;:&#39; or a &#39;&#92;0&#39; */
            len--;                                          [4]
            c=sk_SSL_CIPHER_value&#40;sk,i&#41;;
            for &#40;cp=c-&gt;name; *cp; &#41;
                    {
                    if &#40;len-- &lt;= 0&#41;                         [1]
                            {
                            *p=&#39;&#92;0&#39;;                        [5]
                            return&#40;buf&#41;;
                            }
                    else
                            *&#40;p++&#41;= *&#40;cp++&#41;;                [2]
                    }
            *&#40;p++&#41;=&#39;:&#39;;                                     [3]
            }
    p[-1]=&#39;&#92;0&#39;;
    return&#40;buf&#41;;

    The old vulnerability got fixed at [1] by comparing &#39;len&#39;
    against &lt;= 0 instead of == 0 to detect the possible
    underflow of &#39;len&#39;.

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

Vendor response:

    2007/06/06      Initial contact with [email protected]
    2007/07/06      Response received by Ben Laurie &lt;[email protected]&gt;
                    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&#40;&#41; function from
    the OpenSSL library up to 0.9.7m and 0.9.8e.