<<< Date Index >>>     <<< Thread Index >>>

mod_security 1.7RC1 to 1.7.1 vulnerability



Program:                mod_security (www.modsecurity.org)
Versions:               1.7RC1 to 1.7.1 (Apache 2 version)
Synopsis:               malloc based buffer overflow
Author:                 Adam Dyga (adeon(at)o2.pl, ad(at)adsystems.com.pl)
URL:                    http://adsystems.com.pl/adg-mod_security171.txt
Discovered:             October 24, 2003
Published:              October 28, 2003

Issue:

        There is a exploitable malloc based buffer overflow in
        mod_security (apache 2 version).
        When appropriately exploited this can lead to (under some circumstances 
-               
        remote) code execution on a vulnerable system with apache server user   
        
        privileges.

Details:

        The bug exists in sec_filter_out() function in apache2/mod_security.c :

        <snip>

                if (ctx->bufused + len > ctx->buflen) {
            char *newbuffer;
            // todo: implement a smarter extension policy
            unsigned long int newsize = ctx->buflen * 2;

            sec_debug_log(r, 3, "sec_filter_out: expanding buffer to %i", 
newsize);

            // allocate a larger buffer
            newbuffer = apr_palloc(f->r->pool, newsize + 1);
            memcpy(newbuffer, ctx->buffer, ctx->bufused);
            // free(ctx->buffer);

            ctx->buffer = newbuffer;
            ctx->buflen = newsize;
            ctx->input_ptr = ctx->buffer + ctx->bufused;
        }

        memcpy(ctx->input_ptr, data, len);
        ctx->input_ptr += len;
        ctx->bufused += len;

        </snip>

        As we can see, if ctx->buffer is too small, it's size is doubled, 
regardless of
        the size of     incoming data. If incoming data size is larger than
        (ctx->buflen*2 - ctx->bufused) then the second memcpy may overwrite 
further header(s) of
        the next chunks on the heap. The author assumed, that incoming data 
size is not
        larger than 8kB, because Apache internally transports data in chunks 
that are
        4kB/8kB long. However, this is not true when data is sent by server 
side script.

        This is a piece of mod_security debug log:

        sec_filter_out: got 198301 bytes, bufused=0, buflen=16384
        sec_filter_out: expanding buffer to 32768

        The buffer is overflowed when server side script is generating large 
output,
        for example when writing large file to the output:

        <?php
                Header('Content-Type: image/jpeg');
                readfile('some_large_image.jpeg');
        ?>

        When getting the 'some_large_image.jpeg' directly from server (not by 
the above
        script, but by using GET method instead), the buffer overflow doesn't 
occur.

        So, to perform an attack, the attacker has to have the possibility to 
upload his/her own
        script to the server (very common on web hosting servers) or to use 
some XSS bug found on
        the site.

        The sec_filter_out() function is called when the mod_security.so module 
is just loaded,
        no other directives in httpd.conf (from mod_security) are needed.

Remedies:

        Upgrade to 1.7.2, which fixes the vulnerability. If that is not
        possible, turn output filtering off with "SecFilterScanOutput Off".

Vendor status:

        October 24, 2003 - ivanr@xxxxxxxxxxxxxx notified, no response
        October 25, 2003 - ivanr@xxxxxxxxxxxxxx notified, got response
        October 28, 2003 - patched version of mod_security 1.7.2 released
        October 28, 2003 - public disclosure