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