CVE‑2025‑31133 - luka w runc poprzez nadużycie maskedPaths i wyścig montowania - Security Bez Tabu

CVE‑2025‑31133 – luka w runc poprzez nadużycie maskedPaths i wyścig montowania

TL;DR

CVE‑2025‑31133 to luka w runc umożliwiająca ucieczkę z kontenera poprzez nadużycie maskedPaths i wyścig montowania. Skutkiem jest możliwość zapisu do wybranych plików /proc hosta w trakcie startu kontenera. Traktujemy to jako zachowanie odpowiadające technice ATT&CK T1611 (Escape to Host). Łatki: runc 1.2.8, 1.3.3 (i 1.4.0‑rc.3). W chmurze dostawcy (np. AWS) odnotowali brak ryzyka „cross‑tenant” i wypchnęli zaktualizowane obrazy/runtime. Priorytet: wysoki – pilne aktualizacje + detekcje operacji na /proc i anomalii montowania.


Krótka definicja techniczna

CVE‑2025‑31133: luka w runc (runtime OCI) polegająca na niewystarczającej weryfikacji źródła bind‑mountu używanego do maskowania plików (maskedPaths). Podmiana /dev/null na dowiązanie symboliczne do wybranego pliku w procfs pozwala doprowadzić do RW‑mountu docelowego pliku /proc i obejść izolację kontenera, co praktycznie realizuje T1611 Escape to Host.


Gdzie występuje / przykłady platform

  • Linux hosty używające: containerd, CRI‑O, Docker (pod spodem runc). Dotyczy środowisk bare‑metal i VM.
  • Kubernetes (K8s): AKS/AKS‑on‑prem, EKS, GKE oraz własne klastry – podczas tworzenia/uruchamiania podów/kontenerów.
  • AWS: EKS/ECS – AWS wydał biuletyn, zaktualizował AMI/ECS i wskazał brak ryzyka cross‑customer.
  • Azure/GCP: klastry AKS/GKE (runtime z runc); aktualizacje dystrybucyjne. [Brak specyficznej luki w usługach pakietu M365/AD].
  • ESXi/Windows: sama luka dotyczy runc (Linux), natomiast T1611 formalnie obejmuje również VM/ESXi/Windows jako platformy techniki na poziomie ATT&CK (nie w kontekście tego konkretnego CVE).

Szczegółowy opis techniki (jak działa, cele, dlaczego skuteczna)

T1611 – Escape to Host opisuje działania prowadzące do wyjścia poza izolację kontenera/VM w celu uzyskania dostępu do hosta. W przypadku CVE‑2025‑31133 vektor opiera się o błąd w maskedPaths (OCI). W czasie startu kontenera runc bind‑mountuje /dev/null na wybrane ścieżki, by je „zamaskować”. Brak twardej weryfikacji inoda /dev/null umożliwiał podstawienie symlinku do kontrolowanego pliku /proc i spowodowanie RW‑mountu tego pliku – co otwierało możliwość zapisu do wybranych kontrolnych plików procfs i eskalacji poza granice kontenera. To wpisuje się w katalog przypadków, w których nadużycie montowań/namespace’ów prowadzi do ucieczki (T1611).


Artefakty i logi (SOC)

Warstwa / źródłoCo obserwowaćPrzykładowe pola / zdarzeniaUwaga
Linux auditd / eBPFSyscall mount z opcją MS_BIND na ścieżki pod /proc//dev podczas startu kontenera; próby open/write do /proc/SYSCALL=mount, rekordy PATH z name=/proc/...; exe=/usr/bin/runc / containerd-shim; eBPF: mount, openat(O_WRONLY) na /proc/sys/*Wysoka wartość korelacji z chwilą tworzenia kontenera
Journald / daemonLogi runc/containerd/CRI‑O przy tworzeniu zadań, błędy montowaniarunc[...], containerd: CreateTask, crio: Running containerWłącz poziom info/debug w labie
Kubernetes Auditverb=create/update dla pods/deployments + podejrzane securityContext lub hostPath do /proc, /sys, /devrequestObject.spec.volumes[].hostPath.path, securityContext.privileged=true, hostPID=trueHeurystyka – nie każda taka konfiguracja to atak
CloudTrail (ECS)RegisterTaskDefinition, RunTask, UpdateService ze znacznikami privileged=true, host-mounty do /proc//dev, readonlyRootFilesystem=falseeventSource=ecs.amazonaws.com, requestParameters.containerDefinitionsDla EKS użyj K8s Audit Logs / CloudWatch logów kontrol‑plane
K8s Node / cgroupNietypowe procesy poza namespaces, nowe monty na hoście tuż po starcie poda/proc/self/mountinfo, nsenter ślady, wpisy w dmesgWspomagaj eBPF do obserwacji

Źródła ogólne dot. T1611 (platformy, taktyka, detekcje) oraz CVE‑2025‑31133 (opis i wydania) potwierdzają powyższe artefakty.


Detekcja (praktyczne reguły)

Sigma — Linux auditd (wykrycie podejrzanych bind‑mountów do /proc w trakcie startu kontenera)

title: Suspicious Bind-Mount To /proc During Container Start (CVE-2025-31133 aligned)
id: 2dc7b2d7-7c3a-4f1c-9e4c-31133a01
status: experimental
description: Detects runc/containerd bind-mounts targeting /proc paths (maskedPaths abuse pattern)
logsource:
  product: linux
  service: auditd
detection:
  sel_syscall:
    syscall: mount
  sel_bind:
    a2|contains: "MS_BIND"
  sel_path_proc:
    name|startswith: "/proc/"
  sel_proc:
    exe|endswith:
      - "/runc"
      - "/containerd-shim"
      - "/crio"
  condition: sel_syscall and sel_bind and sel_path_proc and sel_proc
fields:
  - exe
  - comm
  - pid
  - uid
  - name
  - cwd
falsepositives:
  - legalne agenty monitoringu montujące /proc read-only (np. node-exporter)
level: high
tags:
  - attack.t1611

Uwaga: składnia pól a*/name jest zależna od formatu eksportu auditd; w razie potrzeby dostosuj parser. Reguła jest heurystyczna – celem jest sygnał do korelacji. (Patrz też ATT&CK Detection Strategy for Escape to Host).

Splunk (Linux auditd / journald)

(index=linux_audit OR index=syslog)
| eval msg=coalesce(_raw,message)
| regex msg="(SYSCALL=mount| mount\\s)"
| search msg="/proc/" msg="bind" (msg="/usr/bin/runc" OR msg="containerd-shim" OR msg="crio")
| stats count min(_time) as first_seen max(_time) as last_seen by host, process, pid, user
| where count>0

KQL (Azure, AKS – Kubernetes Audit)

KubeAudit
| where verb in ("create","update")
| where objectRef.resource in ("pods","deployments","daemonsets")
| where tostring(requestObject.spec.securityContext.privileged) =~ "true"
   or tostring(requestObject.spec.hostPID) =~ "true"
   or array_length(requestObject.spec.volumes) > 0
| extend hostPath = pack_array(requestObject.spec.volumes)
| where tostring(hostPath) has_any ("/proc","/sys","/dev")
| project TimeGenerated, userAgent, user=username, objectRef, requestObject

(Por. matryca Containers i detekcje T1611).

CloudTrail (AWS CloudWatch Logs Insights – ECS)

fields @timestamp, eventName, userIdentity.arn, requestParameters
| filter eventSource="ecs.amazonaws.com"
| filter eventName in ["RegisterTaskDefinition","RunTask","UpdateService"]
| filter requestParameters like /"privileged":\s*true/ 
    or requestParameters like /"readonlyRootFilesystem":\s*false/
    or requestParameters like /\/proc|\/dev/
| sort @timestamp desc

(AWS doręczył zaktualizowane AMI/zmiany w ECS – mimo to monitoruj definicje zadań).

Elastic / EQL (Linux – zapisy do /proc/sys z przestrzeni kontenera)

file where event.type == "change" and
  file.path like "/proc/sys/%" and
  process.name not in ("systemd-sysctl","sysctl") and
  process.executable in ("/usr/bin/runc","/usr/bin/python3","/usr/bin/bash","/bin/bash","/usr/bin/sh")

(Wspiera korelację z innymi sygnałami T1611).


Heurystyki / korelacje

  • Łańcuch zdarzeń: Pod/Task create ⟶ nietypowe monty /proc//dev ⟶ zapis do /proc/sys/* ⟶ procesy na hoście poza namespaces. Korelować w oknie ±60 s od startu kontenera.
  • Konfiguracja ryzykowna: privileged=true, hostPID=true, hostPath do / lub /proc. To nie jest exploit sam w sobie, ale zwiększa powierzchnię ataku.
  • U dostawców chmurowych: sprawdzaj automatyczne roll‑outy AMI/agentów runtime; brak „cross‑tenant” ≠ brak ryzyka węzła.

False positives / tuning

  • Agenty monitoringu (Node Exporter, Falco, EDR dla K8s) montujące /proc ReadOnly.
  • Zadania administracyjne/serwisowe (diagnoza jądra) mogą chwilowo dotykać mount//proc/sys.
  • Tuning: whitelista namespace’ów (kube-system, monitoring), obrazy podpisane, etykiety DaemonSet’ów, procesy znanych agentów; thresholding na liczbę i typ modyfikowanych plików /proc.

Playbook reagowania (IR)

Cel: szybkie odseparowanie ryzyka, walidacja wersji runc, aktualizacja oraz łowienie śladów ewentualnego wyjścia na hosta.

  1. Triaga i izolacja
  • Zidentyfikuj node z alertu; na K8s: kubectl cordon <node> && kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
  • Wstrzymaj harmonogramowanie nowych zadań (ECS deployment pause / K8s scale 0 dla krytycznych workloadów).
  1. Walidacja wersji runtime
runc --version || rpm -q runc || dpkg -l | grep -E '^ii\s+runc'
containerd --version && crictl --version

Sprawdź czy ≥ 1.2.8/1.3.3 (lub 1.4.0‑rc.3).

  1. Łowy (host)
  • Przejrzyj świeże monty: grep proc /proc/self/mountinfo
  • Szukaj zapisów do /proc/sys/* w ostatnich minutach (auditd/eBPF).
  • Sprawdź procesy poza namespaces kontenera.
  1. Łowy (control plane)
  • K8s Audit: create/update z privileged=true/hostPath do /proc|/dev.
  • ECS/CloudTrail: RegisterTaskDefinition/RunTask z privileged=true, readonlyRootFilesystem=false.
  1. Remediacja
  • Aktualizacja runc przez repo dystrybucji (RHEL/Ubuntu/SUSE publikują advisories).
  • Restart usług containerd/crio/docker; rollout nowych Podów/Tasków.
  • Wymuś polityki: Pod Security Standards, brak privileged, brak hostPID i niepotrzebnych hostPath.
  1. Po incydencie
  • Rotacja sekretów używanych na node (jeśli istnieją oznaki wyjścia na hosta).
  • Hardening: seccomp/apparmor/SELinux profili i read‑only rootfs.

Przykłady z kampanii / case studies

  • Upstream disclosure (listy oss‑sec, 5–7 listopada 2025): opis trzech podatności runc umożliwiających pełne ucieczki przez zapisy do /proc. Wskazano, że realna dotkliwość w środowiskach Docker/K8s może być postrzegana jako wyższa niż „perspektywa runc”.
  • AWS bulletin: automatyczne działania (nowe AMI/placement zadań), brak ryzyka cross‑customer.
  • ATT&CK – przykłady procedur T1611: TeamTNT i inne przypadki nadużyć prowadzących do eskalacji na hosta (historycznie, różne wektory).

Lab (bezpieczne testy) — przykładowe komendy

Wyłącznie w odizolowanym labie/VM! Celem jest walidacja detekcji, nie odtwarzanie exploita.

  1. Obserwacja zdarzeń mount (auditd)
sudo auditctl -D
sudo auditctl -a always,exit -F arch=b64 -S mount -k mounts_monitor
# akcja testowa: nieszkodliwy bind-mount w /tmp (na hoście)
sudo mkdir -p /tmp/lab && sudo mount -o bind /proc /tmp/lab
sudo ausearch -k mounts_monitor | aureport -f
sudo umount /tmp/lab
  1. K8s – test heurystyki politycznej (hostPath RO)
apiVersion: v1
kind: Pod
metadata: { name: lab-hostpath-ro, namespace: default }
spec:
  containers:
  - name: sleeper
    image: alpine
    command: ["sh","-c","sleep 600"]
    volumeMounts:
    - name: hostproc
      mountPath: /host_proc
      readOnly: true
  volumes:
  - name: hostproc
    hostPath: { path: /proc, type: Directory }

Zastosuj kubectl apply -f ... i sprawdź, czy logika z sekcji 7 (KQL/Sigma na K8s Audit) generuje sygnał.
(Nie wykonuj zapisów do /proc; to test konfiguracji, nie eksploatacji).

  1. Weryfikacja wersji – sprawdź, że runtime ≧ wersje z poprawkami (sekcja 10).

Mapowania (Mitigations, powiązane techniki)

Mitigations (ATT&CK):

  • M1048 – Application Isolation & Sandboxing (seccomp ograniczający mount, PSS w K8s).
  • M1038 – Execution Prevention (read‑only kontenery, minimalne obrazy, SELinux/AppArmor).
  • M1026 – Privileged Account Management (zakaz privileged, brak root‑a by default).
  • M1042 – Disable or Remove Feature or Program (usuwanie zbędnych narzędzi).
  • M1051 – Update Software (szybkie łatanie runtime/AMI).

Powiązane techniki (korelacje):

  • T1609 – Container Administration Command (nadużycie kubelet/API/Docker).
  • T1610 – Deploy Container (wstrzyknięcie nowej definicji z ryzykowną konfiguracją).
  • T1613 – Container and Resource Discovery (rozpoznanie środowiska przed ucieczką).

Źródła / dalsza lektura

  • MITRE ATT&CK T1611 (Escape to Host) – opis, taktyka, mitigacje, detekcje. (MITRE ATT&CK)
  • MITRE ATT&CK – Detection Strategy for Escape to Host (AN0612). (MITRE ATT&CK)
  • ATT&CK – wersje (v18.0 aktywna od 2025‑10‑28). (MITRE ATT&CK)
  • runc v1.3.3 / v1.2.8 – wydanie z poprawkami i opis CVE (upstream GitHub Releases). (GitHub)
  • NVD – karta CVE‑2025‑31133 (opis). (NVD)
  • Sysdig – analiza nowych luk runc (maskedPaths). (Sysdig)
  • oss‑security (Aleksa Sarai) – disclosure + komentarz dot. CVSS i 3 luk. (Openwall)
  • Ubuntu / USN i strona CVE. (Ubuntu)
  • SUSE advisory (wersje z łatkami, w tym 1.4.0‑rc.3). (SUSE)
  • AWS bulletin – działania w EKS/ECS, brak cross‑tenant. (Amazon Web Services, Inc.)

Checklisty dla SOC / CISO

SOC (operacyjne):

  • Wdrożone reguły z sekcji 7 (auditd/eBPF + K8s Audit + CloudTrail).
  • Korelacja „Pod create ↔ bind‑mount /proc ↔ write /proc/sys”.
  • Lista dozwolonych podów/agentów montujących /proc (RO) – tuning FP.
  • Dashboard wersji runc/containerd/CRI‑O węzłów (≥ 1.2.8/1.3.3/1.4.0‑rc.3).
  • Alert na privileged=true, hostPID=true, hostPath do /proc|/sys|/dev.

CISO (strategiczne):

  • Polityki PSS/PSA w K8s – brak kontenerów uprzywilejowanych.
  • SLA na aktualizacje runtime/AMI w chmurze (potwierdzony rollout).
  • Wymóg profili seccomp/AppArmor/SELinux dla workloadów.
  • Przegląd uprawnień DevOps do rejestracji definicji zadań (ECS) i tworzenia Podów (K8s).

Uwaga o rozbieżnościach wersji podatnych: NVD wskazuje konkretne zakresy wersji; upstream runc deklaruje, że problem dotyczył „wszystkich znanych wersji” przed wydaniami naprawczymi – w praktyce przyjmij konserwatywnie aktualizację do wersji z poprawką.