abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sonic-gnmi-noauth
技术分析文章:https://abraxaslabs.tech/research/sonic-gnmi-noauth
SONiC gNMI f13a08e0440f - SONiC Foundation / sonic-net
社区版 SONiC NOS。不是 Dell Enterprise SONiC。不是 SonicWall SonicOS。该委员会不签发 CVE。gnmi-native.sh 知道省略 --client_auth 过去会完全禁用身份验证,因此当 user_auth 缺失时,它会强制使用证书模式。失败即关闭(Fail-closed)。然而,当证书不存在时,它从不传递 --ca_crt。setupFlags 因为没有 CA 而取消设置证书。authenticate() 将空映射视为成功。原生写入和 translib 写入仍被编译在内(ENABLE_NATIVE_WRITE=y)。两组生产标志集,同样的跳过:默认 ToR --noTLS --bind_address 127.0.0.1;SmartSwitch DPU --insecure --allow_no_client_auth,空绑定,所有接口,端口 8080。
证书取消设置后为空的 UserAuth 意味着未经身份验证的 gNMI Set 和 gNOI 写入。没有证书的 DPU 在 :8080 上可远程访问。
| ID | 暂无 CVE |
| CWE | CWE-306, CWE-287 |
| CVSS | 严重:9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H(DPU 无证书)。默认 ToR 在 127.0.0.1:8080 上存在同样的跳过(高危,本地)。 |
| 产品 | sonic-gnmi / sonic-buildimage |
| 受影响版本 | sonic-gnmi 至 master f13a08e0440f;启动器 9495839742e4 |
| 认证 | 未经身份验证 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1 |
在没有 gNMI 证书的 SmartSwitch DPU 上:从网络访问 TCP :8080,无需 JWT,无需 PAM,无需客户端证书。调用 gnmi.gNMI/Set(原生 CONFIG_DB / translib)。调用 gnoi.debug.Debug。重启。恢复出厂设置。在 /tmp、/var/tmp、/host 下执行 File.Put。
在没有证书的默认 ToR/leaf 上:任何能访问 127.0.0.1:8080 的进程都能做同样的事。gnmi 容器使用主机网络,因此该回环地址就是主机的回环地址。
这就是在未经身份验证的情况下重写交换机配置,并以 admin 身份执行主机命令。调试白名单包括 docker、config、redis-cli、sonic-installer、reboot。默认 admin 属于 docker 组和 %sudo 组。不是文档中记录的默认 admin 密码。在 UserAuth 为空时,KillProcess 仍返回 Unauthenticated。不要将其用作成功判定的依据。
我先阅读了 SECURITY.md。sonic-net/SONiC 是 wiki。代码位于同级的 sonic-net/* 代码树中。然后针对这些固定版本进行了十次排查:CLI 注入、REST 认证、gNMI Set、hostcfgd PAM、RESTCONF、ZTP、镜像 Redis/sshd/sudo、FEATURE 默认值、GCU/SSTI、DHCP/LLDP/SNMP。没有使用真实交换机。标准是严重/高危。
其中大部分条目已经关闭或并非默认启用。sonic-restapi 是 INCLUDE_RESTAPI ?= n。RESTCONF 的生产启动器强制使用 PAM。主机 Redis 是 127.0.0.1 且没有 requirepass,这属于第一跳,并非发现项。gnmi 容器不是可选的。INCLUDE_SYSTEM_GNMI = y。FEATURE gnmi 已启用。主机网络、主机 pid、主机 userns。
我没有搭建完整的 sonic-vs 镜像。该实验环境是一个轻量级 gRPC 封装,封装了来自 pin f13a08e0440f 的 setupFlags 和 authenticate() 的经 SHA256 校验的提取片段。两个监听器均返回 SONIC-GNMI-NOAUTH-WITNESS,且 auth_enabled=false 和 enable_native_write=true。密码 UserAuth 不带凭据即为 Unauthenticated。这才是真正的跳过,而不是一个总是成功的桩。
已记录的弯路:KillProcess Unauthenticated(该 RPC 已经拒绝空的 UserAuth——实验环境需要 Set-path authenticate() 跳过);当密码 UserAuth 开启且无凭据时 Probe OK(那么 oracle 就是一个桩);一个 gNOI Debug docker gadget、nsenter payload、反向 shell。纯属表演。把这一点指向 Dell Enterprise SONiC 设备,或者 SonicWall。产品不对。
cd lab
./run.sh
仅针对 127.0.0.1:18080(ToR 明文)和 127.0.0.1:18081(DPU TLS 不安全模式)。轻量 gRPC,而非完整 DPU 镜像。构建时针对 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
如果在剥离证书后 UserAuth 为空,则不要提供 Set/gNOI 写入服务,或者不要监听非回环地址。在 --noTLS 路径上也要复制 UserAuth。配置服务器证书和 CA,使 --ca_crt 被设置且证书模式未被取消设置。不要在可访问的 :8080 上运行 SmartSwitch DPU 无证书模式(--insecure --allow_no_client_auth 且 CA 为空)。在写入路径上,当 UserAuth 为空时,两个监听器都必须返回 Unauthenticated。
telemetry.go · server.go · whitelist.go · command.gognmi-native.sh · rules/config · init_cfg.json.j2GNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境使用。不提供任何担保。