CVE-2026-104795 in OpenShift Container Platforminfo

Zusammenfassung

von VulDB • 14.10.2026

Der insights-runtime-extractor wird als privilegiertes DaemonSet (`hostPID: true`) ausgeführt, das Container-Prozesse auf Runtime-Fingerabdrücke (Runtime Fingerprinting) scannt. Beim Scannen eines Containers führt der Koordinator Folgendes aus:

1. **fork()**t einen Kindprozess 2. Wechselt mit **setns()** in die PID- und Mount-Namespace des Zielcontainers 3. Wechselt mit **fchdir()** zurück zu einem verwaisten Dateideskriptor (FD), der auf das eigene Root-Dateisystem des Extractors zeigt (wo `/crio.sock` als hostPath gemountet ist) 4. Ruft **nur `seteuid(target_uid)`** auf — ändert die effektive UID, lässt jedoch die **reale UID und die gespeetzte Set-UID bei 0** und behält den zulässigen Capability-Satz (permitted capability set) 5. Die Schutzfunktion `check_no_privileged_perms()` überprüft nur den Satz der effektiven Capabilities (besteht also), und wird **vollständig übersprungen, wenn das Ziel als uid 0 ausgeführt wird** 6. Der Fingerprint `VersionExecutable` ruft `fpr_kind_executable` mit `process.command_line[0]` auf — dem argv[0] des Ziels, gelesen aus `/proc/<pid>/cmdline`, der **vollständig vom Workload kontrolliert** wird
7. `fpr_kind_executable` führt `exec.Command(executable, "--version").Output()` aus — wodurch das **eigene Binärprogramm der Workload** innerhalb des Mount-Namespace der Workload ausgeführt wird, während die reale UID (ruid) im Host-User-Namespace 0 ist

Der ausgeführte Prozess kann `setuid(0)` aufrufen, um vollständige Root-Rechte mit `CAP_SYS_ADMIN` wiederherzustellen, und erbt den verwaisten aktuellen Arbeitsverzeichnispfad (cwd), der in das Dateisystem des Extractor-Containers aufgelöst wird, welches die Host-CRI-O-Socket enthält.

## Betroffener Code

### 1. Unzureichender Abbau von Berechtigungen (Rust — Koordinator des Extractors)

**Datei:** `extractor/src/insights_runtime_extractor.rs`

```rust // Zeilen 139-146 — Nur seteuid wird reduziert, Guard für Root-Container übersprungen join_process_namespaces(process.pid)?; change_dir(current_dir); switch_user(*process.uid)?; if *process.uid != 0 {
perms::check_no_privileged_perms() .expect("Must not have privileged permissions to run fingerprints"); } fingerprint::run_fingerprints(&config, out_dir, &process); ```

```rust // Zeilen 182-185 — Nur effektive UID wird geändert; ruid/suid bleiben bei 0 fn switch_user(uid: u32) -> Result<(), ScannerError> {
debug!("... Becoming user: {uid}");
seteuid(uid.into()).map_err(|e| ScannerError::Errno(e)) } ```

### 2. Ausführung von nicht vertrauenswürdigen Binärdateien (Go — Fingerprinting)

**Datei:** `fingerprints/pkg/utils/file.go`

```go // Zeilen 75-80 — führt einen Pfad aus, der wörtlich aus argv[0] der Workload übernommen wurde
func GetExecutableVersionOutput(executable string) (string, error) {
out, err := exec.Command(executable, "--version").Output() if err != nil {
return "", err } return string(out), nil } ```

### 3. Von der Workload kontrollierter Pfad wird weitergeleitet (Rust — version_executable)

**Datei:** `version_executable.rs`

```rust // Zeilen 29-34 — von der Workload kontrolliertes command_line[0] wird an das Fingerprinting übergeben
return Some(vec![
fpr_kind_executable, out_dir.to_string(), String::from(&process.command_line[0]),
String::from(&version_executable.runtime_kind_name), ]); ```

## Angriffsmuster

**Angreifer:** Jeder Tenant, der einen Pod planen kann (unprivilegiert, beliebiger Namespace) **Opfer:** Der Knoten, auf dem das DaemonSet insights-runtime-extractor ausgeführt wird **Auslöser:** Automatisch — Das DaemonScannt alle Container-Prozesse auf dem Knoten

**Angriffsablauf:**

1. Der Angreifer erstellt einen Pod, dessen Prozessname mit einem konfigurierten Muster für versionierte ausführbare Dateien übereinstimmt (`node`, `python`, `python3`, `MainThread` oder enthält `java`) 2. Das Hauptbinärprogramm des Pods (am Pfad entsprechend argv[0]) ist eine bösartige ausführbare Datei, die `setuid(0)` aufruft, um Root-Rechte wiederherzustellen
3. Wenn der insights-Operator einen Scan auslöst, fork()t das DaemonSet den Prozess, betritt den Mount-Namespace des Angreifers und führt das Binärprogramm des Angreifers mit ruid=0 aus 4. Der Code des Angreifers gewinnt volle Root-Rechte mit `CAP_SYS_ADMIN` im Host-User-Namespace zurück 5. Das vererbte cwd enthält die Host-CRI-O-Socket → vollständige Kompromittierung des Knotens

If you want to get best quality of vulnerability data, you may have to visit VulDB.

Zuständig

Redhat

Reservieren

02.10.2026

Veröffentlichung

14.10.2026

Moderieren

akzeptiert

Eintrag

VDB-419797

EPSS

0.00000

KEV

nein

Aktivitäten

low

Quellen

Do you want to use VulDB in your project?

Use the official API to access entries easily!