
Documenta e reproduz uma falha de autenticação fail-open no SONiC gNMI, onde um mapa UserAuth vazio permite gravações gNMI Set e gNOI não autenticadas, com um harness de laboratório em loopback.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sonic-gnmi-noauth
SONiC gNMI f13a08e0440f - SONiC Foundation / sonic-net
NOS SONiC da comunidade. Não é o Dell Enterprise SONiC. Não é o SonicWall SonicOS. O comitê não emite CVEs. O gnmi-native.sh sabe que omitir --client_auth costumava desabilitar a autenticação por completo, então quando user_auth está ausente ele força o modo cert. Fail-closed. Depois ele nunca passa --ca_crt quando os certificados estão ausentes. O setupFlags remove o cert porque não há CA. O authenticate() trata o mapa vazio como sucesso. Escritas nativas e translib permanecem compiladas (ENABLE_NATIVE_WRITE=y). Dois conjuntos de flags de produção, mesmo skip: ToR padrão --noTLS --bind_address 127.0.0.1; SmartSwitch DPU --insecure --allow_no_client_auth, bind vazio, todas as interfaces, porta 8080.
UserAuth vazio após a remoção do cert é gNMI Set e escritas gNOI não autenticadas. DPU sem certificados é remoto em :8080.
| ID | sem CVE ainda |
| CWE | CWE-306, CWE-287 |
| CVSS | Crítico: 9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (DPU sem cert). ToR padrão é o mesmo skip em 127.0.0.1:8080 (Alto, local). |
| Produto | sonic-gnmi / sonic-buildimage |
| Afetado | sonic-gnmi até master f13a08e0440f; launcher 9495839742e4 |
| Auth | não autenticado |
| Licença | GNU Affero GPL v3.0 |
| Lab | somente 127.0.0.1 |
Em um SmartSwitch DPU sem certificados gNMI: a partir da rede, TCP :8080, sem JWT, sem PAM, sem certificado de cliente. Chamar gnmi.gNMI/Set (CONFIG_DB nativo / translib). Chamar gnoi.debug.Debug. Reboot. Factory reset. File.Put em /tmp, /var/tmp, /host.
Em um ToR/leaf padrão sem certificados: qualquer processo que consiga alcançar 127.0.0.1:8080 faz o mesmo. O container gnmi está em host net, então esse loopback é o do host.
Isso é reescrita de configuração do switch, e comandos no host como admin, sem autenticar. A whitelist de Debug inclui docker, config, redis-cli, sonic-installer, reboot. O admin padrão está em docker e %sudo. Não é a senha admin padrão documentada. KillProcess ainda retorna Unauthenticated com UserAuth vazio. Não use isso como oráculo de sucesso.
Eu li o SECURITY.md primeiro. sonic-net/SONiC é a wiki. O código está nas árvores irmãs sonic-net/*. Depois, dez caçadas nesses pins: injeção de CLI, auth REST, gNMI Set, PAM do hostcfgd, RESTCONF, ZTP, Redis/sshd/sudo da imagem, padrões de FEATURE, GCU/SSTI, DHCP/LLDP/SNMP. Nenhum switch real. O critério era Crítico/Alto.
A maior parte desse critério já está fechada ou não é padrão. sonic-restapi é INCLUDE_RESTAPI ?= n. O launcher de produção do RESTCONF força PAM. O Redis do host é 127.0.0.1 sem requirepass, o que é um primeiro salto, não um achado. O container gnmi não é opcional. INCLUDE_SYSTEM_GNMI = y. A FEATURE gnmi está habilitada. Host net, host pid, host userns.
Eu não levantei uma imagem sonic-vs completa. O lab é um gRPC fino que encapsula extratos verificados por SHA256 de setupFlags e authenticate() do pin f13a08e0440f. Ambos os listeners retornaram SONIC-GNMI-NOAUTH-WITNESS com auth_enabled=false e enable_native_write=true. UserAuth por senha sem credenciais é Unauthenticated. Esse é o skip real, não um stub que sempre tem sucesso.
Caminhos errados já registrados: KillProcess Unauthenticated (esse RPC já rejeita UserAuth vazio - o lab exige o skip de authenticate() no caminho Set); Probe OK quando UserAuth por senha está ativo e sem credenciais (então o oráculo é um stub); um gadget docker do gNOI Debug, payload nsenter, reverse shell. Teatro. Apontar isso para uma máquina Dell Enterprise SONiC, ou um SonicWall. Produto errado.
cd lab
./run.sh
Alvo somente 127.0.0.1:18080 (ToR em texto claro) e 127.0.0.1:18081 (DPU TLS-insecure). gRPC fino, não uma imagem DPU completa. Extratos do pin com hash na build contra sonic-gnmi f13a08e0440f.
IOC tor-connect 127.0.0.1:18080 plaintext no-metadata
IOC tor-check witness=SONIC-GNMI-NOAUTH-WITNESS auth_enabled=false enable_native_write=true user_auth_any=false mode=tor
IOC dpu-connect 127.0.0.1:18081 tls-insecure no-client-cert no-metadata
IOC dpu-check witness=SONIC-GNMI-NOAUTH-WITNESS auth_enabled=false enable_native_write=true user_auth_any=false mode=dpu
IOC tor-negative status=UNAUTHENTICATED
IOC dpu-negative status=UNAUTHENTICATED
SUCCESS SONIC-GNMI-NOAUTH who=unauth tor=18080 dpu=18081 SONIC-GNMI-NOAUTH-WITNESS
Se UserAuth estiver vazio após remover o cert, não sirva Set/escrita gNOI, ou não escute fora do loopback. Copie UserAuth também no caminho --noTLS. Provisione certificados de servidor e uma CA para que --ca_crt seja definido e o modo cert não seja removido. Não execute SmartSwitch DPU sem cert (--insecure --allow_no_client_auth com CA vazia) em um :8080 alcançável. Ambos os listeners devem retornar Unauthenticated para UserAuth vazio no caminho de escrita.
telemetry.go · server.go · whitelist.go · command.gognmi-native.sh · rules/config · init_cfg.json.j2GNU Affero GPL v3.0. Veja LICENSE. Somente lab em loopback. Sem garantia.