CVE-2024-3177 / Host Escape

CVE-2024-3177: Kubernetes Windows Worker Node Container Escape Teardown

How insecure named pipe security descriptors on Windows worker nodes in pkg/kubelet/winstats allowed container processes to impersonate NT AUTHORITY\SYSTEM.

💡 身近な例えで分かる解説 (ELI5)

Imagine a hospital where patients are confined to their recovery rooms, communicating with doctors through an intercom tube. If the hospital installed cheap intercom tubes that don't verify who is speaking, a patient can whisper into the tube claiming to be the chief surgeon, ordering the pharmacy to unlock all drug cabinets.

中核となる概念とサブシステム用語

Windows Worker Nodes
Kubernetes nodes running Windows Server to orchestrate .NET and Windows container workloads.
Named Pipes
A Windows IPC mechanism used by the kubelet agent to monitor container statistics and process health.
Security Descriptor (SDDL)
Security Descriptor Definition Language: Windows syntax defining which users can read, write, or impersonate over an IPC channel.
Impersonation Token
A Windows security token allowing a server thread to execute actions using the client's security context.

ステップ別エクスプロイト実行メカニズム

Step 1

1. Compromise Container on Windows Node

An attacker gains execution inside a container pod scheduled on a Windows node.

Step 2

2. Connect to Host Named Pipe

The container connects to the kubelet's unauthenticated named pipe (\\.\pipe\k8s-winstats).

Step 3

3. Trigger Host Impersonation

The container induces the kubelet service to call ImpersonateNamedPipeClient().

Step 4

4. SYSTEM Shell Execution

Because the kubelet runs as SYSTEM, the attacker breaks out to full host administrator.

ソースコード比較:致命的バグ vs 安全な修正

日常的な開発者が直感的に理解できる高級言語コードで提示(バイナリやアセンブリ不使用)。

未修正の脆弱なコード
// VULNERABLE: pkg/kubelet/winstats/winstats.go before patch
func createStatsPipe() (net.Listener, error) {
    // ROOT CAUSE:
    // Empty security descriptor grants World Read/Write permissions to all containers!
    // Allows unprivileged container processes to connect and manipulate impersonation tokens!
    return winio.ListenPipe(`\\.\pipe\k8s-winstats`, &winio.PipeConfig{
        SecurityDescriptor: "", // Insecure default permissions!
    })
}
修正済みの安全なコード
// SECURE: pkg/kubelet/winstats/winstats.go patch
func createStatsPipe() (net.Listener, error) {
    // 1. Enforce strict SDDL restricting access exclusively to Local System and Admins
    // "D:(A;;GA;;;SY)(A;;GA;;;BA)" -> Discretionary ACL: Grant All to SYSTEM and Built-in Admins
    sddl := "D:(A;;GA;;;SY)(A;;GA;;;BA)"
    
    return winio.ListenPipe(`\\.\pipe\k8s-winstats`, &winio.PipeConfig{
        SecurityDescriptor: sddl, // Strictly blocks container processes!
    })
}

開発現場向けシステム堅牢化チェックリスト

← セキュリティディレクトリ一覧 すべてのセキュリティ更新情報 →