
Proof-of-concept exploit per CVE-2025-31324, un upload di file non autenticato in SAP NetWeaver Visual Composer, con indicazioni di rilevamento, mapping MITRE e passaggi di remediation.
Tipo: Proof of Concept — Ricerca sulle Vulnerabilità CVE: CVE-2025-31324 CVSS: 10.0 Critico (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H) Stato: Corretto — SAP Security Note 3594142 + 3604119 Aggiunto al CISA KEV: Maggio 2025
⚠️ Questo PoC utilizza un file JSP benigno ("Hello World") per validare la superficie di attacco senza eseguire codice malevolo. Uso esclusivo in ambienti autorizzati per scopi di pentesting e sviluppo di rilevamenti.
Developed by: HKK$ cat ./vulnerability_summary.txtLa vulnerabilità CVE-2025-31324 risiede nel componente Visual Composer Metadata Uploader di SAP NetWeaver AS Java — un difetto di missing authorization check che consente a qualsiasi attaccante non autenticato di inviare richieste POST all'endpoint /developmentserver/metadatauploader, risultando in un upload non limitato di file arbitrari.
La CVE colpisce specificamente il SAP NetWeaver Visual Composer Framework versione 7.50, con punteggio CVSS 10.0 — il massimo possibile.
Gli attaccanti hanno sfruttato attivamente questa vulnerabilità da gennaio a maggio 2025, installando webshell persistenti in centinaia di sistemi in tutto il mondo.
$ cat ./impact.txtOperando con privilegi elevati e in prossimità dei dati ERP, il lateral movement verso stack SAP ABAP o database connessi è banale dopo lo sfruttamento.
La catena di sfruttamento completa negli attacchi reali:
Upload JSP (CVE-2025-31324)
→ Webshell persistente sul server
→ RCE come processo SAP (alto privilegio)
→ Accesso ai dati ERP (Finance, HR, Supply Chain)
→ Lateral movement verso ABAP / DB
→ Deploy di framework C2 (es: Brute Ratel)
$ cat ./architecture.txt┌─────────────────────────────────────────────────────────────────────────┐
│ CVE-2025-31324 — EXPLOIT FLOW │
│ │
│ ATTACCANTE SAP NETWEAVER AS JAVA │
│ │
│ POST /developmentserver/metadatauploader │
│ Content-Type: multipart/form-data ┌─────────────────────┐ │
│ Body: file JSP/WAR/qualsiasi ────────────► │ Metadata Uploader │ │
│ (senza autenticazione) │ │ │
│ │ ❌ Nessuna verifica │ │
│ │ di auth │ │
│ │ ❌ Nessuna validaz. │ │
│ │ dell'estensione │ │
│ │ ❌ Nessuna sanitiz. │ │
│ │ del contenuto │ │
│ └────────┬────────────┘ │
│ │ │
│ File salvato in: │
│ /irj/root/ o simile │
│ │ │
│ GET /irj/hello_world.jsp ◄──────────────────────────┘ │
│ → Hello World (PoC benigno) │
│ → Webshell (exploit reale) │
└─────────────────────────────────────────────────────────────────────────┘
Il /developmentserver/metadatauploader fa parte del SAP Visual Composer — uno strumento di sviluppo low-code per analisti di business per creare applicazioni SAP senza codice Java. L'endpoint è stato progettato per ricevere modelli di metadata durante lo sviluppo. Sebbene il componente non sia abilitato nella configurazione predefinita di NetWeaver, Onapsis ha segnalato che è ampiamente attivato negli ambienti di produzione.
$ cat ./design_decisions.mdfile_content = """<%@ page language="java" contentType="text/html; charset=UTF-8" ...%>
<h1>Hello World</h1>"""
Perché JSP e non un altro formato?
SAP NetWeaver AS Java esegue una JVM — i file .jsp vengono interpretati direttamente dal servlet container (Apache Tomcat integrato) senza compilazione preventiva. Questo rende JSP il formato ideale per webshell in ambienti Java.
La scelta del contenuto benigno ("Hello World") è deliberata per il PoC:
Nello sfruttamento reale, il contenuto sarebbe una webshell JSP con esecuzione di comandi, es:
<%
String cmd = request.getParameter("cmd");
Runtime.getRuntime().exec(cmd);
%>
multipart/form-data — Perché questo Content-Type?files = {'file': (file_name, open(file_name, 'rb'), 'application/octet-stream')}
L'endpoint si aspetta una richiesta multipart/form-data — lo stesso formato usato dai moduli HTML di upload file. Questo è intenzionale nel design originale del Visual Composer (upload di modelli di sviluppo).
La libreria requests costruisce automaticamente i boundary del multipart quando viene passato files= — l'header Content-Type: multipart/form-data; boundary=... viene generato internamente.
verify=False: disabilita la validazione del certificato TLS — necessario perché gli ambienti SAP usano spesso certificati self-signed. In produzione, usare verify='/path/to/ca-bundle.crt'.
https://<host>:<port>/developmentserver/metadatauploader?CONTENTTYPE=MODEL&CLIENT=1
| Componente | Significato |
|---|---|
:50201 | Porta predefinita di SAP ICM (Internet Communication Manager) HTTPS |
/developmentserver/ | Servlet di sviluppo del Visual Composer |
metadatauploader | Endpoint specifico per l'upload di metadata |
CONTENTTYPE=MODEL | Tipo di contenuto atteso dall'endpoint |
CLIENT=1 | Mandante SAP (client) — 000, 100, 001 sono comuni |
$ cat ./mitre_mapping.ymltactic: Initial Access
- T1190 # Exploit Public-Facing Application
# Sfruttamento dell'endpoint /developmentserver/metadatauploader
# senza autenticazione via HTTP POST
tactic: Execution
- T1505.003 # Server Software Component: Web Shell
# JSP webshell caricata → eseguita dal servlet container (Tomcat)
tactic: Persistence
- T1505.003 # Web Shell come meccanismo di persistenza
# Il file JSP persiste nel filesystem del server tra i riavvii
tactic: Defense Evasion
- T1036 # Masquerading
# Webshell denominate come file SAP legittimi (es: metadata.jsp)
tactic: Discovery
- T1082 # System Information Discovery
# Post-RCE: enumerare processi, utenti, percorsi SAP
tactic: Lateral Movement
- T1210 # Exploitation of Remote Services
# Accesso allo stack ABAP, database connessi via RCE
tactic: Collection
- T1005 # Data from Local System
# Accesso diretto ai dati ERP (Finance, HR, Supply Chain)
$ cat ./affected_versions.txt