PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Testet eure Apache Server auf die neue 0-Day DOS-Lücke

with 19 comments

Ich möchte wenig Zeit verlieren: Heute wurde ein sehr leichter Angriff bekannt, mit dem man viele voll gepatchte Apache 2.2 Server ziemlich einfach abschießen kann. Details dazu finden sich sowohl bei Heise als auch bei Golem.

Es geht also um den HTTP Range-Header. Eigentlich dazu gedacht, Downloads zu pausieren und zu resumen, ist der Apache anfällig wenn man ihm sehr viele Ranges hinwirft, er verbraucht dann unheimlich viel RAM, geht dann an den Swap-Speicher, und dann beginnt Linux damit Prozesse zu beenden weil der Arbeitsspeicher total überlastet ist. Wenn man Pech hat kommt man nicht mal mehr via SSH drauf.

Es gibt einen Exploit, der in Perl geschrieben ist, und der einen Server erst darauf testet ob er anfällig ist, und wenn er es ist, beginnt er damit viele Requests loszuschicken mit vielen Range-Headern. Nach wenigen Sekunden ist der Server nicht mehr erreichbar. Dieser Exploit wird von Heise und Golem verlinkt, also nahezu jeder Script-Kiddy wird nun loslaufen und es benutzen, es wird nur Perl und das Perl-Modul Parallel::ForkManager benötigt.

Achso, das Apache Team hat versprochen innerhalb von 48 Stunden einen Patch zu liefern. Bis dahin bleiben einem nur wenige Möglichkeiten: Range-Support ganz ausschalten, oder via .htaccess zumindestens einschränken. Wie das geht findet ihr auch in den Artikeln bei Heise und Golem. Oder einen Reverse-Proxy nutzen der nicht anfällig ist.

Hier habe ich ein kleines Script in PHP, das einen Webserver auf Anfälligkeit testet (Zend Framework wird benötigt in diesem Fall, ich arbeite noch an einer kurzen Version ohne Zend Framework):

<?php

require_once 'Zend/Http/Client.php';
$client = new Zend_Http_Client();
$client->setHeaders('Range', 'bytes=0-4');
$client->setMethod(Zend_Http_Client::HEAD);
$client->setUri('https://www.phpgangsta.de');

$response = $client->request();

if (strpos($response->getMessage(), 'Partial') !== false) {
    echo "wahrscheinlich anfällig: ".$response->getMessage()."\n\n";
} else {
    echo "wahrscheinlich nicht anfällig: ".$response->getMessage()."\n\n";
}

Es wird also ein Request abgeschickt mit der Bitte um eine Range, und wenn der Server mit einem „Partial Content“ reagiert ist er vielleicht angreifbar, wenn es ein Apache-Server ist.

php head.php
wahrscheinlich anfällig: Partial Content

HTTP/1.1 206 Partial Content
Date: Wed, 24 Aug 2011 18:56:31 GMT
Server: Apache
X-powered-by: PHP/5.2.4-2ubuntu5.17
Set-cookie: PHPSESSID=143dfef48a6275aa726bc03af0901b5f; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-encoding: gzip
Content-range: bytes 0-4/20
Content-length: 5
Connection: close
Content-type: text/html; charset=UTF-8

Wer dann ganz sicher gehen will ob er anfällig ist probiert den oben erwähnten Perl-Exploit aus, der wie gesagt viele Requests verschickt mit großen Ranges, und dann den Webserver zum Erliegen bringt. Man sollte aber sicherstellen dass man nicht eine URL probiert die keine Weiterleitung enthält (301, 302), denn das Perl-Script folgt der Weiterleitung nicht. Es muss ein URL zu einer gültigen existierenden Datei sein.

Written by Michael Kliewe

August 24th, 2011 at 9:01 pm

Posted in PHP

19 Responses to 'Testet eure Apache Server auf die neue 0-Day DOS-Lücke'

Subscribe to comments with RSS or TrackBack to 'Testet eure Apache Server auf die neue 0-Day DOS-Lücke'.

  1. Danke für die Info. Scheint keine sehr schöne Sache zu sein, da könnte man ja potentiell reichlich Websites mit lahmlegen…

    Patrick

    24 Aug 11 at 21:07

  2. Version ohne Zend: https://gist.github.com/1169049 🙂

    Fabian

    24 Aug 11 at 22:05

  3. @Fabian: Dafür braucht man curl, was auch nicht alle haben 😉

    Michael Kliewe

    24 Aug 11 at 22:12

  4. 2 schöne Skripte. Hier gibt es noch meins dazu:

    http://www.phpmonkeys.de/2011/08/24/apache-killer-vulnerability-check/

    Arbeitet nur mit Sockets, simpler ist eigentlich nur noch telnet 😛

    Norbert

    24 Aug 11 at 22:55

  5. @Michael: Stimmt. Wobei ich keinen einzigen Host mehr kenne (außer 1&1 glaube ich ;)), der curl nicht aktiviert hat. Gott sei Danke: cURL ftw! 🙂

    Fabian

    24 Aug 11 at 23:37

  6. Mir sind heute zufällig 2 Websites aufgefallen die deswegen gehackt wurden. Scheint schon gut ausgenutzt zu werden… Danke für den Beitrag!

    Ricardo

    25 Aug 11 at 01:19

  7. 	$url = 'https://www.phpgangsta.de/';
    	$ch = curl_init($url);
       
    	curl_setopt($ch, CURLOPT_HEADER, 1);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    	curl_setopt($ch, CURLOPT_NOBODY, true);
    	curl_setopt($ch, CURLOPT_HTTPHEADER, array('Range: bytes=0-4'));
    	
    	$rawdata = curl_exec($ch);
    	curl_close ($ch);
    	
    	//var_dump($rawdata);
    	
    	if (strpos($rawdata, 'Partial') !== false) {
    		echo "wahrscheinlich anfällig.\r\n";
    	}
    	echo "wahrscheinlich nicht anfällig.\r\n";

    Andy

    25 Aug 11 at 08:45

  8. Man merkt gerade, dass zu viele Programmierer auch als SysAdmins operieren müssen… 😉

    Phil

    25 Aug 11 at 10:07

  9. Laut einem Kommentar bei meinem Gist sollte unbedingt „Accept-Encoding: gzip“ mitgeschickt werden: https://gist.github.com/1169049#comments

    Fabian

    25 Aug 11 at 11:53

  10. @Fabian: Danke für den Tipp, mein Script tut das bereits, Zend_Http_Client macht das automatisch:

    HEAD / HTTP/1.1
    Host: http://www.phpgangsta.de
    Connection: close
    Accept-encoding: gzip, deflate
    User-Agent: Zend_Http_Client
    Range: bytes=0-4

    Norbert hat es auch (schon) drin.

    Michael Kliewe

    25 Aug 11 at 11:57

  11. Führt das nun dazu, dass alle keine RequestHeader mit Range mehr akzeptieren? Dann kann man ja praktisch alle Downloadmanager in die Tonne kloppen. Die Variante mit den angepassten Rewrite-Rules gefällt mir besser.

    PS: Bei meinen 1&1-Servern gibt’s curl 😀

    Martin

    25 Aug 11 at 15:36

  12. Ja, ich glaube die Rewrite-Rule ist die beste Variante, oder in den nächsten Tagen den Apache updaten 😉

    Michael Kliewe

    25 Aug 11 at 15:54

  13. Um zu prüfen ob die gängigen Patches mit mod_rewrite etc auch wirklich greifen sollte man jedoch auch mal 6 Ranges mitschicken:

    Range:bytes=0-4,5-8,9-12,13-16,17-20,21-24

    Sven

    30 Aug 11 at 20:06

  14. Das Apache-Update 2.2.20 ist da:
    http://www.golem.de/1108/86098.html

    Für 1.3 und 2.0 gibts noch keine Updates.

    Michael Kliewe

    31 Aug 11 at 12:52

  15. Gibt es unter Windows ein Updater dafür? Oder muss ich Apache ganz neu installieren und konfigurieren?

    Tobias

    5 Sep 11 at 17:46

  16. @Tobias: Gute Frage, nutzt du den Original Apache oder eine WAMP/XAMPP Variante? Je nachdem was genau du nutzt ist das generelle Vorgehen glaube ich immer:
    – Konfiguration sichern (httpd.conf etc + php.ini usw, evtl. htdocs falls genutzt)
    – Stoppen des Apache
    – Deinstallieren
    – Neu Installieren
    – Konfiguration wieder einspielen bzw. Einstellungen in die neuen .conf Dateien übernehmen
    – Apache starten

    Gibt aber noch einige Details die man beachten kann, wie beispielsweise vorher einen Restore-Punkt anzulegen. Die beste Anleitung die ich auf die Schnelle finden konnte:
    http://www.daleisphere.com/how-to-upgrade-to-apache-2210-with-windows-xp/

    Ich habe einen XAMPP laufen unter Windows, nur die Zip-Variante, keine Windows-Dienste, da tausche ich immer das komplette Verzeichnis aus, passe die Konfigurationen wieder an und fertig. Ist sehr unkompliziert. So oft brauche ich ihn aber auch nicht.

    Michael Kliewe

    5 Sep 11 at 18:02

  17. Ja ich nutze Original Apache. Ich dachte vlt. gibt es unter Windows auch ein Updater, wie bei Linux. Dort kann man das Update einfach über die Konsole einspielen.

    Denn ich wollte nähmlich nicht Apache wieder komplett neu einrichten, aber da wird mir wohl nichts anderes über bleiben.

    Tobias

    6 Sep 11 at 15:13

  18. […] und heise verlinkt und somit werden wir die nächsten Tage noch viel “Spaß” haben. Der PHPGangsta hat eine Implementierung eines Checkers vorgestellt, die auf dem Zend Framework aufbaut. Da dies […]

  19. […] Kliewe präsentiert auf seinem Blog eine Lösung mit dem Zend Framework: Testet eure Apache Server auf die neue 0-Day DOS-Lücke. Der “Nachteil” liegt auf der Hand – ohne das Zend Framework kommt man nicht […]

Leave a Reply

You can add images to your comment by clicking here.