antoine: Zwei Dateien includen!

Hi!

Mithilfe eines Freundes hab ich es geschafft, folgenden Code zu programmieren:

<?php
if(isset($_GET["show"]) && file_exists($_GET["show"].".php")) {
include($_GET["show"].".php");
} else {
include("home.php");
}
?>

Das hab ich jetzt in meiner index.php stehen.
Wenn ich index.php?show=irgendwas aufrufe, dann wird die php-Datei included, die ich für irgendwas eingebe.
Klappt auch, allerdings gibts da noch ein Problem.

Ich würde gerne ZWEI dateien auf diese weise includen können.
wisst ihr, wie ich das hinbekomme, dass ich 2 dateien in eine includen kann und diese beiden dateien selbstständig angeben kann?

  1. Hello,

    Mithilfe eines Freundes hab ich es geschafft, folgenden Code zu programmieren:

    Mit diesem Freund brauchst Du keine Feinde mehr!

    Das, was da "programmiert" wurde, ist so ziemlich die gefährlichste Standard-Sicherheitslücke, die es gibt. Lad das bloß nicht auf öffentlich zugänglichen PHP-Server hoch.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

    1. Mit diesem Freund brauchst Du keine Feinde mehr!

      dem stimme ich ausserdem voll zu! Mein Tip ist also nur zur Verständigung aber nicht zur Benutzung auf öffentlichen Systemen, wenn Du Deine Skripte auch sicher machen möchtest...

      Gruss,
      waki

    2. Sorry, ich bin ein php-laie, ich hab keine ahnung wovon ihr sprecht!
      was ist daran denn unsicher? o.O

      es funktioniert doch ganz in ordnung

      1. es funktioniert doch ganz in ordnung

        Hacker oder ähnliches könnten ziemlich gefährliche Sachen da eingeben und z.b. deine Seite kapput machen, da sie so gut wie jede php-Datei da includen können, die die wollen, unter Umständen sogar Dateien von einem ganz anderen Server.

        1. Oh, das habe ich nicht gewusst.
          Ich dachte ich könnte nur Dateien includen, die auf meinem Server liegen ..

          Wie gesagt, bin ein PHP-Laie.
          Ließe sich das ohne viel Kenntnisse sicher machen?

          1. Ließe sich das ohne viel Kenntnisse sicher machen?

            Na ja.. ich denke, um es sicher zu machen dürfte es ausreichend sein, wenn Du prüfst, ob die angegebene php-Datei auf Deinem Server liegt.. in einem bestimmten Ordner zB..

            Noch besser wäre, wenn Du nur eine Art Alias übergibst.

            Von der Logik dann ungefähr so:

            Wenn Parameter=Karl
            dann include karl.php
            sonst include nix.php

            :D

            Schöne Grüße
            Meta

            1. Php-laie, vergessen?

              Ich kann kein php, weiß also absolut gar nicht, wie ich das umsetzen könnte :'(

              1. Hallo antoine.

                Ich kann kein php, weiß also absolut gar nicht, wie ich das umsetzen könnte :'(

                Setze hier noch vor das $_GET… ein $_SERVER['DOCUMENT_ROOT']:

                file_exists($_GET["show"].".php")

                Damit überprüfst du, ob die jeweilige Datei *wirklich* im Wurzelverzeichnis (DocumentRoot) deines Webspaces liegt.

                Allgemein solltest du, wenn du es sicher einsetzen willst, dich aber intensiver mit PHP befassen. Das Handbuch hilft hier in den meisten Fällen weiter.

                Einen schönen Donnerstag noch.

                Gruß, Ashura

                --
                sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                mathbr:del.icio.us/ mathbr:w00t/
            2. Hello,

              Noch besser wäre, wenn Du nur eine Art Alias übergibst.

              Von der Logik dann ungefähr so:

              Wenn Parameter=Karl
              dann include karl.php
              sonst include nix.php

              Das meint jetzt zwar das Richtige, ist aber besch..... erklärt:

              $_includes = array();
                $_includes[1] = 'karl.php';
                $_includes[2] = 'paul.php';
                $_includes[3] = 'dora.php';

              if( isset($_GET['do'] and isset($_includes[$_GET['do']]) )
                {
                  $ok = include_once($_includes[$_GET['do']]);
                }

              Der Aufruf findet dann mit

              domain.tld/script.php?do=1

              statt.

              Hier wird nun erst überprüft, ob überhaupt was zu tun ist.
              Dann wird überprüft, ob der passende Index in der Wertemenge enthalten ist
              Und dann wird genau das ausgeführt, was vorbestimmt ist.

              Wir haben also eine abgeschlossene Wertemenge und ein geschlossenes System.

              Harzliche Grüße vom Berg
              http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau

              1. [...] aber besch..... erklärt:

                :D

                Ich hab mir halt gedacht irgendjmd möchte das gerne mal aus'm Eff-Eff zaubern ;) [1]

                Schöne Grüße
                Meta

                [1] Oder ich kann kein php

                1. Hello,

                  [1] Oder ich kann kein php

                  Das ist nicht das Problem.
                  Die Wahrscheinlichkeit ist aber hoch, dass jemand da gleich den nächsten Fehler macht.

                  Wenn man nämlich anstelle eines Arrays für die Whitelist nur eine normale Variable nehmen würde, könnte man ggf. schon wieder etwas einschleppen bei register_globals = on.

                  Arrays sind aber auch bei dieser (register_globals = on)-Einstellung vom Einschleppen von Werten sicher, zumindest soweit ich bisher weiß.

                  Das Problem an solchen Threads ist sowieso ein zweischneidiges, da sie sowohl Warnung als auch Anleitung sind.

                  Harzliche Grüße vom Berg
                  http://www.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau

                  1. echo $begrüßung;

                    Arrays sind aber auch bei dieser (register_globals = on)-Einstellung vom Einschleppen von Werten sicher, zumindest soweit ich bisher weiß.

                    Ach was...

                    http://example.org/script.php?foo[]=bar&foo[x]=baz

                    Oder meintest du was anderes?

                    Und auch mit dem $GLOBALS kann/konnte man Schindluder treiben: http://www.hardened-php.net/globals_overwite_and_its_consequences.76.html

                    echo "$verabschiedung $name";

                    1. Hello,

                      Arrays sind aber auch bei dieser (register_globals = on)-Einstellung vom Einschleppen von Werten sicher, zumindest soweit ich bisher weiß.

                      Ach was...

                      http://example.org/script.php?foo[]=bar&foo[x]=baz

                      Oder meintest du was anderes?

                      Nö. Ich meinte genau DAS, hatte mich aber bisher noch nicht so intensiv damit beschäftigt, dass ich das probiert habe. Werde ich schnellstmöglich nachholen.

                      Wenn Du da Recht hast, sollten wir aber nun wirklich eine Kampagne gegen "register_globals = on" und alle ihre Spielarten ( extract() usw. ) lostreten.

                      Harzliche Grüße vom Berg
                      http://www.annerschbarrich.de

                      Tom

                      --
                      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                      Nur selber lernen macht schlau

      2. Hello,

        Sorry, ich bin ein php-laie, ich hab keine ahnung wovon ihr sprecht!
        was ist daran denn unsicher? o.O

        es funktioniert doch ganz in ordnung

        Wenn Du mir sagst, wo das Script zu erreichen ist, übernehme ich damit Deinen Server... Zumindest DEN Teil, den auch dein Script erreichen kann. Und bei den meisten Providern dürfte das fast der ganze Server sein. Und wenn ich will, geht das sogar so, dass Du lange nichts davon merkst.

        Man kann mittels dieser Konstruktion jedes Script von außen auf Deinen Server laden und zur Ausführung bringen.

        Der einzige teilweise Schutz gegen Missbrauch liegt darin, dass ggf. die "fopen wrapper" abgeschaltet sind. Darüber gibt die Funktion phpinfo() Aufschluss.

        Harzliche Grüße vom Berg
        http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau

    3. Moin!

      Mit diesem Freund brauchst Du keine Feinde mehr!

      Das, was da "programmiert" wurde, ist so ziemlich die gefährlichste Standard-Sicherheitslücke, die es gibt. Lad das bloß nicht auf öffentlich zugänglichen PHP-Server hoch.

      Tom, du erzählst Blödsinn.

      Hier nochmal der fragliche Code, schöner formatiert:

        
      <?php  
      if (isset($_GET["show"]) && file_exists($_GET["show"].".php"))  
      {  
        include($_GET["show"].".php");  
      }  
      else  
      {  
        include("home.php");  
      }  
      ?>  
      
      

      Analysieren wir mal, wo grundsätzlich die Gefahr liegt: Ganz klar im include-Befehl, der grundsätzlich in der Lage wäre, auch entfernten Code (url_fopen_wrapper) einzufügen.

      Allerdings steht der einzige include-Befehl, der das könnte, innerhalb einer IF-Abschnitts, und die Eingangsbedingung dafür ist:
      1. $_GET[show] muß gesetzt sein.
      2. Im lokalen Dateisystem muß eine $_GET['show']-Datei mit der Endung ".php" existieren.

      file_exists kann nicht mithilfe von url_fopen_wrapper entfernte Dateien testen, es greift immer auf das lokale Dateisystem zu.

      Und da Angreifer auf das lokale Dateisystem keinen Zugriff haben, können sie keinen eigenen Code einschleusen.

      Auch reale Fremd-Accounts auf Shared-Hosting-Systemen dürften grundsätzlich nicht relevant sein, weil die Accounts hinsichtlich der Dateizugriffe gegeneinander abgeschottet sein sollten - andernfalls hätte man auf solchen Servern aber noch ganz andere Probleme, und diese potentielle Lücke wäre nur ein i-Tüpfelchen.

      Deine Allgemein-Aussage, mit diesem Code würdest du jeden Server übernehmen können, ist jedenfalls falsch.

      - Sven Rautenberg

      --
      My sssignature, my preciousssss!
      1. Hello,

        Tom, du erzählst Blödsinn.

        Bist Du da 100% sicher?

        1. Im lokalen Dateisystem muß eine $_GET['show']-Datei mit der Endung ".php" existieren.
          file_exists kann nicht mithilfe von url_fopen_wrapper entfernte Dateien testen, es greift immer auf das lokale Dateisystem zu.

        siehe:
        http://de2.php.net/manual/en/function.file-exists.php

        Blauer Kasten.

        Ich habe leider kein php 5.x zur Verfügung.
        Daher wäre ich begeistert, wenn das jemand mal auf einer 5er-Version ausprobieren könnte

        Harzliche Grüße vom Berg
        http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau

        1. Hallo Tom,

          siehe:
          http://de2.php.net/manual/en/function.file-exists.php
          Blauer Kasten.
          Ich habe leider kein php 5.x zur Verfügung.

          Ich schon, aber...
          Bei mir (PHP 5.0.1 als Modul in Apache 2.049 unter Win2k/SP4) leugnet file_exists() die Existenz jeglicher Dateien, wenn ich eine HTTP-Ressource als Argument übergebe.

          Daher wäre ich begeistert, wenn das jemand mal auf einer 5er-Version ausprobieren könnte

          Ob die Win32-Implementierung von PHP so ganz repräsentativ ist, weiß ich nicht - aber in dem "blauen Kasten" steht ja auch nur "with /some/ URL wrappers". Also ganz klar eine Einschränkung, "es gibt welche, wo es funktioniert, aber nur ein paar".

          Schönen Abend noch,
           Martin

          --
          Computer funktionieren grundsätzlich nicht richtig.
          Wenn doch, hast du etwas falsch gemacht.
          1. Hello,

            Bei mir (PHP 5.0.1 als Modul in Apache 2.049 unter Win2k/SP4) leugnet file_exists() die Existenz jeglicher Dateien, wenn ich eine HTTP-Ressource als Argument übergebe.

            Wer sagt denn, dass es HTTP sein muss?

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

        2. Hallo Tom.

          Ich habe leider kein php 5.x zur Verfügung.
          Daher wäre ich begeistert, wenn das jemand mal auf einer 5er-Version ausprobieren könnte

          Bitte:

          <?php  
            
          error_reporting(E_ALL);  
            
          if (isset($_GET['res'])) {  
            
            if (file_exists($_GET['res'])) {  
               echo 'The resource "'.$_GET['res'].'" exists!';  
            } else {  
               echo 'The resource "'.$_GET['res'].'" does not exist.';  
            }  
          }  
            
          ?>
          

          Einen schönen Donnerstag noch.

          Gruß, Ashura

          --
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
          mathbr:del.icio.us/ mathbr:w00t/
          1. Hello Ashura,

            Bitte:

            Probier mal das:
            http://dev.noctus.net/php/file_exists.php?res=ftp%3A%2F%2Fde.selfhtml.org%2Findex.htm

            Da sollte man ggf. noch mal nachfassen, oder?

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

            1. Hello Ashura,

              Hi Tom.

              Bitte:

              Probier mal das:
              http://dev.noctus.net/php/file_exists.php?res=ftp%3A%2F%2Fde.selfhtml.org%2Findex.htm

              Sollte dies *hier* einen Unterschied machen?

              Da sollte man ggf. noch mal nachfassen, oder?

              Inwiefern?

              Einen schönen Donnerstag noch.

              Gruß, Ashura

              --
              sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
              mathbr:del.icio.us/ mathbr:w00t/
              1. Hello,

                Probier mal das:
                http://dev.noctus.net/php/file_exists.php?res=ftp%3A%2F%2Fde.selfhtml.org%2Findex.htm

                Sollte dies *hier* einen Unterschied machen?

                Da sollte man ggf. noch mal nachfassen, oder?

                Nun, hier kommt nicht gar keine Antwort, sondern eine Fehlermeldung, dass der Connect nicht geklappt hat. Ich habe auch kein Passwort angegeben. Ich habe keinen FTP-Server, den ich über Dein Script gerne testen würde, ob er antwortet.

                Ich hätte aber den Verdacht, dass er das tun würde.

                Harzliche Grüße vom Berg
                http://www.annerschbarrich.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau

                1. Hallo Tom.

                  Nun, hier kommt nicht gar keine Antwort, sondern eine Fehlermeldung, dass der Connect nicht geklappt hat.

                  Ah, das „ftp://“ sehe ich gerade erst.

                  Ich habe auch kein Passwort angegeben. Ich habe keinen FTP-Server, den ich über Dein Script gerne testen würde, ob er antwortet.

                  Ich hätte aber den Verdacht, dass er das tun würde.

                  Per URL mit username:password@host, oder?

                  Wenn ja: die Datei existiert laut file_exists() nicht.

                  Einen schönen Donnerstag noch.

                  Gruß, Ashura

                  --
                  sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                  mathbr:del.icio.us/ mathbr:w00t/
              2. Moin!

                Probier mal das:
                http://dev.noctus.net/php/file_exists.php?res=ftp%3A%2F%2Fde.selfhtml.org%2Findex.htm

                Sollte dies *hier* einen Unterschied machen?

                Da SELFHTML nicht dauerhaft einen FTP-Server betreibt, ist diese URL logischerweise nicht erreichbar.

                Aber das hier geht:
                http://dev.noctus.net/php/file_exists.php?res=ftp://ftp.ccc.de/INDEX

                Da sollte man ggf. noch mal nachfassen, oder?

                Bedauerlicherweise: Ja!

                Dass file_exists in PHP 5 in seinem Verhalten dahingehend verändert wurde, dass es nicht mehr nur lokal arbeitet, ist gravierend! Das reißt mit Sicherheit in etlichen Skripten Lücken, die dort nicht erwartet wurde.

                Man hätte da besser remote_file_exists() erfinden können.

                - Sven Rautenberg

                --
                My sssignature, my preciousssss!
                1. Hallo Sven.

                  Dass file_exists in PHP 5 in seinem Verhalten dahingehend verändert wurde, dass es nicht mehr nur lokal arbeitet, ist gravierend! Das reißt mit Sicherheit in etlichen Skripten Lücken, die dort nicht erwartet wurde.

                  Deshalb auch mein Vorgehen.

                  Man hätte da besser remote_file_exists() erfinden können.

                  Wäre auf jeden Fall eine sicherere Option für bestehende Skripte gewesen.

                  Einen schönen Donnerstag noch.

                  Gruß, Ashura

                  --
                  sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                  mathbr:del.icio.us/ mathbr:w00t/
        3. Moin!

          Tom, du erzählst Blödsinn.

          Bist Du da 100% sicher?

          Nein, ich nehme alles zurück!

          Das vorgestellte Skript ist unter PHP 5 mit url_fopen_wrapper angreifbar durch FTP-URLs, weil file_exists() dort auch FTP checken kann.

          siehe:
          http://de2.php.net/manual/en/function.file-exists.php

          Blauer Kasten.

          Der blaue Kasten ist nur in der englischen Version eingeblendet, im deutschen fehlt er!

          - Sven Rautenberg

          --
          My sssignature, my preciousssss!
        4. Hallo Tom,

          Ich habe leider kein php 5.x zur Verfügung.

          Was hindert dich daran dir eines runterzuladen und zu installieren? - Es muss ja nicht über die vorhandene Version sein, ich habe auch 3 funktionsfähige Versionen (4.4, 5.0 und 5.1) hier.

          Grüße aus Nürnberg
          Tobias

          1. Hello,

            Ich habe leider kein php 5.x zur Verfügung.
            Was hindert dich daran dir eines runterzuladen und zu installieren? - Es muss ja nicht über die vorhandene Version sein, ich habe auch 3 funktionsfähige Versionen (4.4, 5.0 und 5.1) hier.

            Hast Du im Prinzip Recht.
            Ich werde das mal in Angriff nehmen.
            Welche 5er-Version sollte ich denn nehmen, damit mir nichts verlorengeht?
            Da war doch neulich erst ein Hinweis, dass irgendwas, was ich wichtig brauche, in der letzten 5er nicht mehr drin ist...

            Ich hätte es mir aufschreiben müssen!

            Arbeitet denn die 5er-Version noch mit MySQL 3.23.55 zusammen? Da war doch auch was?
            Die kann ich nicht austauschen. Das wäre mir dann zuviel Stress, da zwei Konfigurationen parallel zu fahren.

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

            1. Hallo Tom,

              Welche 5er-Version sollte ich denn nehmen, damit mir nichts verlorengeht?

              Was soll den verlorengehen? Aber ich würde die aktuellste 5.1er nehmen, du kannst aber natürlich auch beim 5.0er Zweig bleiben (ich weiß allerdings nicht, ob es da noch Löcher gibt, die mit der 5.1.0er gestopft wurden).

              Da war doch neulich erst ein Hinweis, dass irgendwas, was ich wichtig brauche, in der letzten 5er nicht mehr drin ist...

              MySQL?

              Ich hätte es mir aufschreiben müssen!

              hehe, das kenn ich :-)

              Arbeitet denn die 5er-Version noch mit MySQL 3.23.55 zusammen?

              keine Ahnung - ausprobieren :-)
              <vermutung art="ganz wage">wenn es nicht funktioniert, hilft vielleicht eine ältere MySQL-Bibliothek aus einer alten PHP-Version</vermutung>

              Grüße aus Nürnberg
              Tobias

              1. Hello,

                Da war doch neulich erst ein Hinweis, dass irgendwas, was ich wichtig brauche, in der letzten 5er nicht mehr drin ist...
                MySQL?

                Nee, das war was anderes.

                Ich weiß nicht mehr, was die da aus der letzten 5er rausgenommen haben. Weiß nur noch, dass ich keinesfalls drauf verzichten konnte.

                Harzliche Grüße vom Berg
                http://www.annerschbarrich.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau

                1. Hallo,

                  MySQL?

                  Nee, das war was anderes.

                  Ich weiß nicht mehr, was die da aus der letzten 5er rausgenommen haben. Weiß nur noch, dass ich keinesfalls drauf verzichten konnte.

                  das einzige, was mir bis jetzt aufgestoßen ist: DIO wurde nach PECL verschoben ;(

                  Gruß aus Berlin!
                  eddi

                  --
                  Wer Rechtschreibfehler findet, darf sie behalten.
                  1. Hello,

                    das einzige, was mir bis jetzt aufgestoßen ist: DIO wurde nach PECL verschoben ;(

                    Na, darauf hätte ich doch selber kommen können *tztz*
                    Das brauche ich dringend.

                    Bis zu welcher Version war das denn dabei?

                    Harzliche Grüße vom Berg
                    http://www.annerschbarrich.de

                    Tom

                    --
                    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                    Nur selber lernen macht schlau

                    1. Re:

                      DIO

                      Bis zu welcher Version war das denn dabei?

                      Meiner Meinung nach ist die Erweiterung ab 5.1.0 in den Sourcen nicht mehr enthalten (Die englische Version der Doku ist wie immer aktueller). Besonders ärgerlich ist dabei, das ein --enable-dio keinerlei Fehlermeldungen an der Shell produziert. Ich habe ewig suchen müssen, bis ich bemerkte, das der Fehler nicht in den Scripten ist ;(

                      Es läßt sich aber sehr einfach mittels phpize und php-config einfach nachinstallieren.

                      Gruß aus Berlin!
                      eddi

                      --
                      Wer Rechtschreibfehler findet, darf sie behalten.
                    2. Hallo Tom,

                      das einzige, was mir bis jetzt aufgestoßen ist: DIO wurde nach PECL verschoben ;(
                      Bis zu welcher Version war das denn dabei?

                      Bis vor 5.1.0, siehe Changelog.

                      Grüße aus Nürnberg
                      Tobias

      2. Moi moin!

        Mit diesem Freund brauchst Du keine Feinde mehr!

        Das, was da "programmiert" wurde, ist so ziemlich die gefährlichste Standard-Sicherheitslücke, die es gibt. Lad das bloß nicht auf öffentlich zugänglichen PHP-Server hoch.

        Tom, du erzählst Blödsinn.

        Das tut er ganz gewiss nicht, denn das Script ist ausreichend, um unter Umständen beliebigen Code (muß nicht mal PHP sein) auszuführen:

        1.) Ich starte einen HTTP-POST-Request mit enthaltenen Files (ein PHP-Script
            und einen Weiteren File).
            Der Request wird vom Server verarbeitet indem Files in das konfigurierte
            UploadVerzeichnis abgelegt werden. Dieses muß von PHP lesbar sein und
            es ist auch innerhalb der open_basedir-Restriction PHPs, da sonst PHP
            keinen Upload verarbeiten könnte. Aktivierte Safmode tut hier NICHTS!
            Somit sind durch UploadVerzeichnis ALLE Sicherheitsmaßnahmen, die PHP zu
            bieten hat, außer Kraft gesetzt.

        2.) Ich starte einen HTTP-GET-Request mit den drei heufigsten UploadVer-
            zeichnisorten => ?show=/tmp ?show=/tmp/php ?show=../tmp
            PHP liefert, per Fehlermeldung schon, das richtige Verzeichnis. Sonst
            einfach testen, testen, testen.

        3.) Habe ich das Uploadverzeichnis so ermittelt kann ich mich mit parallelen
            Requests heranmachen per brut force den Namen zu knacken. Dir Wahrschein-
            lichkeit, daß mir das gelingt ist sehr gering - geht aber bei durch-
            schnittlich 2000 Request pro Minute, die möglich sind, nicht gegen NULL.
            Verlangsame ich den Request zu erstens nach erfolgtem erstem Scriptup-
            load bis auf max_input_time, ist die Wahrscheinlichkeit sehr groß Code
            ausführen zu können.

        Gruß aus Berlin!
        eddi

        --
        Wer Rechtschreibfehler findet, darf sie behalten.
        1. 'Nabend/Moin.

          Eure Ausführungen machen schon ziemlich deutlich, daß es sich um eine ernste Sicherheitslücke handelt. Allerdings kommen mir Aussagen wie "gib mir die Adresse und ich übernehm den Server" etwas übereilt vor. Und zwar aus folgenden Gründen:

          2.) Ich starte einen HTTP-GET-Request mit den drei heufigsten UploadVer-
              zeichnisorten => ?show=/tmp ?show=/tmp/php ?show=../tmp
              PHP liefert, per Fehlermeldung schon, das richtige Verzeichnis.

          Warum sollte PHP durch die übliche Fehlermeldung "No such file _or_ directory" einen Hinweis auf das verwendete Uploadverzeichnis geben? Dir bleibt also nichts weiter übrig, als in den unter 3.) beschriebenen BruteForce-Ansatz auch das Verzeichnis einzubeziehen. Das vermindert die Chancen, die Datei tatsächlich zu finden, noch weiter.

          3.) Habe ich das Uploadverzeichnis so ermittelt kann ich mich mit parallelen
              Requests heranmachen per brut force den Namen zu knacken. Dir Wahrschein-
              lichkeit, daß mir das gelingt ist sehr gering - geht aber bei durch-
              schnittlich 2000 Request pro Minute, die möglich sind, nicht gegen NULL.

          Ich weiß zwar gerade nicht aus dem Kopf, ob es eine feste Vorschrift gibt, nach der PHP den Namen der temporären Datei konstruiert (abgesehen davon, daß er eindeutig sein muß), aber bei mir produziert PHP Namen der Form phpXXXX, wobei XXXX aus [0-9a-zA-Z] ist. Selbst wenn der Präfix "php" als bekannt angesehen werden könnte und diesem -- wie bei mir -- lediglich 4 Zeichen folgen, ergibt sich für das BruteForce ein Aufwand, der sich ziemlich deutlich in den Serverlogs niederschlagen dürfte:

          62 mögliche Zeichen für jede der 4 Stellen macht etwas mehr als 14.7 Mio. Kombinationen. Bei angenommenen 2000 Anfragen pro Minute kommt man auf eine Laufzeit des BruteForcers von reichlichen 5 Tagen. Das sollte doch reichen, um einen Serverdauerbeschuß festzustellen. Auch wenn die durchschnittliche Laufzeit bis zum Finden des Namens kürzer ist... Dazu müßtest du aber tatsächlich schon im richtigen Verzeichnis suchen (siehe Anmerkung zu Punkt 2).

          Verlangsame ich den Request zu erstens nach erfolgtem erstem Scriptup-load bis auf max_input_time, ist die Wahrscheinlichkeit sehr groß Code ausführen zu können.

          Vielleicht liegt es an der fortgeschrittenen Stunde. Aber diesen Satz hab ich leider nicht verstanden... Der war etwas zu konfus. Kannst du bitte nochmal erklären, was du meinst?

          1. Hello,

            es reicht, ein phpinfo() zum Laufen zu bringen, und die Lücken treten zu Tage.

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

          2. Hallo,

            vorab: Gegen den beschriebenen Angriff wäre antoines Script übrigens immun.

            2.) Ich starte einen HTTP-GET-Request mit den drei heufigsten UploadVer-
                zeichnisorten => ?show=/tmp ?show=/tmp/php ?show=../tmp
                PHP liefert, per Fehlermeldung schon, das richtige Verzeichnis.

            Warum sollte PHP durch die übliche Fehlermeldung "No such file _or_ directory" einen Hinweis auf das verwendete Uploadverzeichnis geben? Dir bleibt also nichts weiter übrig, als in den unter 3.) beschriebenen BruteForce-Ansatz auch das Verzeichnis einzubeziehen. Das vermindert die Chancen, die Datei tatsächlich zu finden, noch weiter.

            Leider sind die Admins nicht sehr beflissen PHP zu konfigurieren. Die Wahrscheinlichkeit das UploadVerzeichnis mit nur obigen Angaben zu finden ist, ist groß genug. Viel wichtiger finde ich die Tatsache, daß es die Entwickler versäumten selbst bei aktiviertem safe_mode includes aus dem UplodVerzeichnis abzustellen. (Mit anderen Worten: safe_mode_include_dir greift schlichtweg nicht!)

            3.) Habe ich das Uploadverzeichnis so ermittelt kann ich mich mit parallelen
                Requests heranmachen per brut force den Namen zu knacken. Dir Wahrschein-
                lichkeit, daß mir das gelingt ist sehr gering - geht aber bei durch-
                schnittlich 2000 Request pro Minute, die möglich sind, nicht gegen NULL.

            Ich weiß zwar gerade nicht aus dem Kopf, ob es eine feste Vorschrift gibt, nach der PHP den Namen der temporären Datei konstruiert (abgesehen davon, daß er eindeutig sein muß), aber bei mir produziert PHP Namen der Form phpXXXX, wobei XXXX aus [0-9a-zA-Z] ist. Selbst wenn der Präfix "php" als bekannt angesehen werden könnte und diesem -- wie bei mir -- lediglich 4 Zeichen folgen, ergibt sich für das BruteForce ein Aufwand, der sich ziemlich deutlich in den Serverlogs niederschlagen dürfte:

            62 mögliche Zeichen für jede der 4 Stellen macht etwas mehr als 14.7 Mio. Kombinationen. Bei angenommenen 2000 Anfragen pro Minute kommt man auf eine Laufzeit des BruteForcers von reichlichen 5 Tagen. Das sollte doch reichen, um einen Serverdauerbeschuß festzustellen. Auch wenn die durchschnittliche Laufzeit bis zum Finden des Namens kürzer ist... Dazu müßtest du aber tatsächlich schon im richtigen Verzeichnis suchen (siehe Anmerkung zu Punkt 2).

            Präfix "php" ist gegeben "rfc1867.c". Es sollten sogar "XXXXXX" sein <stdlib.h>. Aber selbst das läßt sich mit parallelen Requests aushebeln. Weitere Ausführungen mache ich dazu nicht!

            Verlangsame ich den Request zu erstens nach erfolgtem erstem Scriptup-load bis auf max_input_time, ist die Wahrscheinlichkeit sehr groß Code ausführen zu können.

            Vielleicht liegt es an der fortgeschrittenen Stunde. Aber diesen Satz hab ich leider nicht verstanden... Der war etwas zu konfus. Kannst du bitte nochmal erklären, was du meinst?

            Der Unter "1.)" beschriebene Upload läßt sich verzögern bis zu einer Zeit max_input_time. (Mal abgesehen davon, daß dieser Wert standardmäßig auf "-1" gesetzt ist; also die Prüfung abgeschaltet ist!)
            Diese Sicherheitslücke wurde durch die sogenannten "Linux-Würmer" auf PHP-Basis ausgenutzt. Nur hat man meiner Ansicht nach die falschen Schlüsse daraus gezogen - nämlich, daß es _nur_ schlechte Scripte sind. Ich sage: Es ist darüber hinaus die mangelnde Aufmerksamkeit beim Konfigurieren PHPs.

            Gruß aus Berlin!
            eddi

            --
            Wer Rechtschreibfehler findet, darf sie behalten.
            1. Hallo.

              Dann werd ich zu den von dir angesprochenen Punkten noch ein bißchen Nachforschungen betreiben und meine eigene Konfiguration nochmal unter diesen Gesichtspunkten checken. Danke dir.

      3. Hello Sven,

        Du hast hier zwei "nicht hilfreich" bekommen.
        Ich bin da anderer Meinung.
        Denn Wenn Du nicht nachgehakt hättest, hätten wir die Sache nicht auf den Punkt gebracht in diesem Thread.

        Ich empfinde (das richtet sich an andere Poster, die eher nicht widersprechen) als hilfreich, die Diskussion auch durchzuführen, wenn man unterschiedlicher Ansicht ist.

        Und Du bist schließlich auch immer bereit, mitzuwirken. Das halte ich für hilfreich!

        Harzliche Grüße vom Berg
        http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau

      4. Moin!

        Mir ist gerade die Idee gekommen, wie man diesen Code hier einfach und simpel absichern kann:

        <?php
        if (isset($_GET["show"]) && file_exists($_GET["show"].".php"))
        {
          include($_GET["show"].".php");
        }
        else
        {
          include("home.php");
        }
        ?>

          
        Das Problem ist, dass der Beginn des Dateinamens dynamisch ist, dort also auch Protokollbezeichner wie ftp:// erscheinen könnten, die unter PHP 5 auch in file\_exists() erlaubt sind und Remote-Zugriffe erlauben - und so zum Includieren von externem bösem Code führen können.  
          
        Dagegen hilft lediglich, sicherzustellen, dass in jedem Fall auf eine Datei aus dem lokalen Dateisystem zugegriffen wird. Und das stellt man sicher, indem der Pfadname mit einem statischen, von Angreifern unabänderlichen Bestandteil beginnt. Also beispielsweise einem "/" plus Document-Root plus Unterverzeichnis im Webprojekt.  
          
        Allerdings: $\_SERVER['DOCUMENT\_ROOT'] steht IIRC nicht in allen Situationen verläßlich zur Verfügung, sondern hängt vom benutzten Webserver ab - und unter Umständen auch von weiteren Einflüssen wie Pfadverschiebungen durch Aliase oder mod\_rewrite. Der Charme des obigen Codes liegt darin, dass durch den relativen Pfadzugriff Anpassungen an den Einsatzort entfallen.  
          
        Aber zum Glück gibts auch einen statischen Bestandteil, der das aktuelle Verzeichnis bezeichnet: "./"  
          
        ~~~php
          
        <?php  
        if (isset($_GET["show"]) && file_exists("./" . $_GET["show"] . ".php"))  
        {  
          include("./" . $_GET["show"] . ".php");  
        }  
        else  
        {  
          include("./home.php");  
        }  
        ?>  
        
        

        So abgesichert würde eine eingeschleppte FTP-URL im Endeffekt so aussehen:
        ./ftp://evil.domain.test/pfad/evilscript.php

        Das führt zu einem lokalen Dateisystemzugriff, der diese "Datei" nicht findet.

        Ich halte meinen Vorschlag für in jeder Situation sicher und deshalb für extrem empfehlenswert. Gibt es Gegenmeinungen?

        - Sven Rautenberg

        --
        My sssignature, my preciousssss!
  2. wie soll den die 2te include-datei lauten?
    die erste soll ja so aussehen: falls $_GET[show]: test, dann:
    test.php

    Falls die 2te datei so heissen soll: test123.php, dann mach doch einfach beide hintereinander:
    if(isset($_GET["show"]) && file_exists($_GET["show"].".php")) {
    include($_GET["show"].".php");
    include("test123.php");
    }

    Gruss,
    waki

  3. Lieber antoine,

    index.php?show=irgendwas&do=irgendwasanderes&var=value

    lässt sich in PHP abfragen mit
    $_GET["show"] // enthält hier "irgendwas"
    $_GET["do"]   // enthält hier "irgendwasanderes"
    $_GET["var"]  // enthält hier "value"

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.