Go-Proof-of-Concept zur Demonstration von CVE-2026-46595 in golang.org/x/crypto/ssh, unter Verwendung von Symbolinspektion gestrippter Binärdateien und Image-Scans zur Verifizierung der anfälligen NewServerConn-Nutzung.
https://www.cve.org/CVERecord?id=CVE-2026-46595 ist https://pkg.go.dev/vuln/GO-2026-5023 eine Schwachstelle im Symbol golang.org/x/crypto/ssh NewServerConn, wie im zweiten Link beschrieben.
Dieses Repository enthält ein einfaches Programm, das einen positiven Schwachstellennachweis demonstriert.
Ein minimaler golang.org/x/crypto/ssh-Server, gepinnt auf x/crypto v0.51.0 (< v0.52.0),
wird verwendet, um zu demonstrieren, dass go tool nm auf nicht gestrippten Binärdateien sowohl positive als auch
negative Prüfungen ermöglicht.
go mod tidy
go build ./...
Da wir das verwundbare Symbol kennen, prüfen wir darauf. Im Moment ist es eine nicht gestrippte Binärdatei, aber wir werden sie strippen, um die Symboltabellen zu entfernen und zu beweisen, dass das verwundbare Symbol in der Ausgabe verbleibt.
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, jetzt strippen und wiederholen
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
Nun prüfen wir die Binärdateien, die in einem OpenShift-Payload-Image ausgeliefert werden.
Extrahieren Sie /usr/bin aus dem Image. --only-files ist erforderlich, da sonst oc image extract
mitten in der Schicht abbricht, wenn es auf einen Symlink wie /usr/bin/ld.so trifft.
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
Für diesen Digest ist das das 4.21 cluster-config-operator-Image:
-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
Sehen Sie, gegen welche Version von x/crypto es gebaut wurde:
$ 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 liegt unter jeder korrigierten Version, daher markieren die Modulversions-Scanner es. Wenden Sie nun die Symbolprüfung an. Neben GO-2026-5023 gibt es weitere golang.org/x/crypto-Schwachstellen, die in v0.55.0 und v0.56.0 behoben wurden, also prüfen Sie alle ihre verwundbaren Symbole auf einmal:
GO-2026-5023 => ssh.NewServerConn GO-2026-6303 => ssh.NewServerConn erneut GO-2026-6354 => ssh.Dial ssh.NewClientConn ssh.NewControlClientConn ssh.NewServerConn GO-2026-6355 => ssh.Dial ssh.NewClientConn ssh.NewControlClientConn ssh.NewServerConn
Die tests-ext-Binärdatei wird gzippt ausgeliefert, also dekomprimieren Sie sie zuerst und prüfen Sie beide:
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)'
Keine Ausgabe, juhu, keine Schwachstelle! Prüfen Sie zur Sicherheit, dass das grep nicht aus dem langweiligen Grund stumm ist, dass es keine Symbole zum Abgleichen gibt:
$ 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 ist also tatsächlich eingelinkt, der Linker hat lediglich das gesamte x/crypto/ssh verworfen, weil
nichts darauf zugreift.
Dies sollte über die anderen Payload-Images hinweg reproduzierbar sein; die einzige Variation pro Image ist,
wo die Binärdateien liegen und ob sie komprimiert sind wie die obige -tests-ext.gz.
Beachten Sie, dass Test-Binärdateien wie *-tests-ext in den Images ausgeliefert werden, obwohl sie auf keinem
Ausführungspfad liegen. Wo sie x/crypto/ssh einbeziehen (das kubernetes k8s-tests-ext
linkt ssh.NewClientConn für seine e2e-SSH-Helfer), liegt es dennoch außerhalb des
Ausführungspfads der laufenden Komponente. Unabhängig davon werden wir daran arbeiten, Test-Binärdateien aus den Images zu entfernen, weil sie
diese größer machen und Dinge wie Image-Pulls verlangsamen.
Das Folgende wurde von Claude beim Erstellen der positiven Testfall-Binärdateien generiert, nicht notwendig für den Nachweis, aber ich habe es drin gelassen.
Dies ist nicht notwendig, um zu beweisen, dass die Schwachstelle existiert, das Obige demonstriert das bereits, aber Sie können dies gerne ebenfalls tun.
go run . -addr 127.0.0.1:2222 -user demo -password demo
Dann, in einem anderen Terminal:
ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null [email protected]
Das Passwort ist demo. Die Sitzung gibt eine Begrüßung aus und gibt Eingaben zurück.
Bei jedem Start wird ein frischer ed25519-Hostschlüssel generiert, sodass nichts auf die Festplatte geschrieben wird.
Bei v0.51.0 meldet govulncheck 10 erreichbare Schwachstellen in
golang.org/x/crypto/ssh, alle zurückverfolgt über main.go →
ssh.NewServerConn (GO-2026-5018 wird ebenfalls über ssh.NewSignerFromKey zurückverfolgt).
go get golang.org/x/[email protected]
go mod tidy
govulncheck ./...
v0.52.0 beseitigt die meisten davon, aber drei benötigen neuere Releases: GO-2026-6303 ist in v0.55.0 behoben, und GO-2026-6354 / GO-2026-6355 in v0.56.0. Ein Scan bei v0.56.0 sollte sauber zurückkommen.