https://www.cve.org/CVERecord?id=CVE-2026-46595 即 https://pkg.go.dev/vuln/GO-2026-5023 如第二个链接所述,这是 golang.org/x/crypto/ssh 中 NewServerConn 符号的一个漏洞。
本仓库包含一个简单的程序,用于演示漏洞检测结果为阳性。
一个最小的 golang.org/x/crypto/ssh 服务器,固定使用 x/crypto v0.51.0(< v0.52.0),
用于演示对未剥离符号的二进制文件运行 go tool nm 既能提供阳性检测结果,也能提供
阴性检测结果。
go mod tidy
go build ./...
既然我们已知存在漏洞符号,就针对它进行检查。目前它是未剥离符号的二进制文件, 但我们会将其剥离以移除符号表,并证明漏洞符号仍然 保留在输出中。
file cve-2026-46595-proof
cve-2026-46595-proof: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=kUaZmGWICI6Buw0K_I7t/L4jXRd3fy2BJy8zNlSYd/lB1_6wYHZLaOLsG0tE26/-FieQlhThdl7AkRj7rl0, BuildID[sha1]=c7ac1dd881dfcaef88a2dd180a8ccb3c5e751e32, with debug_info, not stripped
strings cve-2026-46595-proof | grep golang.org/x/crypto/ssh.NewServerConn
golang.org/x/crypto/ssh.NewServerConn
# ok, now strip it and repeat
strip cve-2026-46595-proof
file cve-2026-46595-proof
cve-2026-46595-proof: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=kUaZmGWICI6Buw0K_I7t/L4jXRd3fy2BJy8zNlSYd/lB1_6wYHZLaOLsG0tE26/-FieQlhThdl7AkRj7rl0, BuildID[sha1]=c7ac1dd881dfcaef88a2dd180a8ccb3c5e751e32, stripped
strings cve-2026-46595-proof | grep -E 'ssh\.(Dial|NewServerConn|NewClientConn|NewControlClientConn)'
golang.org/x/crypto/ssh.NewServerConn
现在,让我们检查 OpenShift 载荷镜像中附带的二进制文件。
从镜像中提取 /usr/bin。必须使用 --only-files,否则 oc image extract
在遇到诸如 /usr/bin/ld.so 之类的符号链接时会在处理该层的过程中中途中止。
IMG=quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:b4dde8227fb99134f71b50f0707eb7f695cfade43b017da3cbc486c2db854fe1
mkdir -p /tmp/cveimg
oc image extract "$IMG" --path /usr/bin/:/tmp/cveimg/ --only-files
ls -laS /tmp/cveimg | head
对于该摘要,这是 4.21 的 cluster-config-operator 镜像:
-rw-r-----. 1 sdodson sdodson 117899168 Feb 24 2026 cluster-config-operator
-rw-r-----. 1 sdodson sdodson 10639741 Feb 24 2026 cluster-config-operator-tests-ext.gz
查看它是针对哪个版本的 x/crypto 构建的:
$ go version -m /tmp/cveimg/cluster-config-operator | grep -E 'go1|x/crypto'
/tmp/cveimg/cluster-config-operator: go1.24.13 (Red Hat 1.24.13-1.el9_6) X:strictfipsruntime
dep golang.org/x/crypto v0.40.0
v0.40.0 低于所有已修复版本,因此模块版本扫描器会将其标记出来。现在应用 符号检查。除了 GO-2026-5023 之外,还有其他 golang.org/x/crypto 漏洞在 v0.55.0 和 v0.56.0 中修复,因此一次性检查它们所有的漏洞符号:
GO-2026-5023 => ssh.NewServerConn GO-2026-6303 => ssh.NewServerConn 再次出现 GO-2026-6354 => ssh.Dial ssh.NewClientConn ssh.NewControlClientConn ssh.NewServerConn GO-2026-6355 => ssh.Dial ssh.NewClientConn ssh.NewControlClientConn ssh.NewServerConn
tests-ext 二进制文件以 gzip 压缩形式提供,因此先解压它,然后检查两者:
gzip -dc /tmp/cveimg/cluster-config-operator-tests-ext.gz > /tmp/cveimg/cluster-config-operator-tests-ext
strings /tmp/cveimg/cluster-config-operator{,-tests-ext} \
| grep -E 'ssh\.(Dial|NewServerConn|NewClientConn|NewControlClientConn)'
没有输出,太好了,没有漏洞!做个健全性检查,确认 grep 没有因为 没有可匹配的符号这种无聊原因而静默:
$ go tool nm /tmp/cveimg/cluster-config-operator | wc -l
150240
$ go tool nm /tmp/cveimg/cluster-config-operator | grep -c golang.org/x/crypto/ssh
0
$ go tool nm /tmp/cveimg/cluster-config-operator-tests-ext | wc -l
24607
$ go tool nm /tmp/cveimg/cluster-config-operator-tests-ext | grep -c golang.org/x/crypto
39
所以 x/crypto 确实被链接进来了,只是链接器丢弃了整个 x/crypto/ssh,因为
没有任何东西引用到它。
这应该可以在其他载荷镜像中重复;每个镜像唯一的差异是
二进制文件所在的位置以及它们是否像上面的 -tests-ext.gz 那样被压缩。
请注意,诸如 *-tests-ext 之类的测试二进制文件会随镜像一起发布,尽管它们
不在任何执行路径上。即使它们确实引入了 x/crypto/ssh(kubernetes 的 k8s-tests-ext
为其 e2e SSH 辅助工具链接了 ssh.NewClientConn),它仍然不在
运行组件的执行路径上。无论如何,我们将努力从镜像中移除测试二进制文件,因为它们
会使镜像变大并拖慢诸如镜像拉取之类的操作。
以下内容是在创建阳性测试用例二进制文件时由 Claude 生成的,对于 概念验证并非必需,但我把它保留了下来。
这对于证明漏洞存在并非必需,上面的内容已经证明了 这一点,但也不妨这样做。
go run . -addr 127.0.0.1:2222 -user demo -password demo
然后,在另一个终端中:
ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null [email protected]
密码是 demo。会话会打印一条问候语并将输入回显回来。
每次启动都会生成一个新的 ed25519 主机密钥,因此不会向磁盘写入任何内容。
在 v0.51.0 中,govulncheck 报告 golang.org/x/crypto/ssh 中有 10 个可达漏洞,
全部通过 main.go →
ssh.NewServerConn 追踪到(GO-2026-5018 还通过 ssh.NewSignerFromKey 追踪)。
go get golang.org/x/[email protected]
go mod tidy
govulncheck ./...
v0.52.0 清除了其中大部分,但有三个需要更新的版本: GO-2026-6303 在 v0.55.0 中修复,GO-2026-6354 / GO-2026-6355 在 v0.56.0 中修复。 在 v0.56.0 下扫描应该返回干净的结果。