CVE-2026-104795
>_ Opis
Tłumaczenie automatyczne – może zawierać nieścisłości.
Ekstraktor Insights-Runtime-Extractor działa jako uprzywilejowany zestaw DaemonSet („hostPID: true”)
który skanuje procesy kontenerowe pod kątem odcisków palców w czasie wykonywania. Podczas skanowania a
kontener, koordynator:
1. **fork()s** jest procesem potomnym
2. **setns()** do przestrzeni nazw PID i montowania kontenera docelowego
3. **fchdir()** powrót do osieroconego FD wskazującego na własny korzeń ekstraktora
system plików (gdzie `/crio.sock` jest zamontowany na HostPath)
4. Wywołuje **tylko `seteuid(target_uid)`** — zmiana efektywnego UID, ale wyjście
**rzeczywisty UID i zapisany zestaw UID na poziomie 0** i **zachowując dozwolone
zestaw możliwości**
5. Strażnik `check_no_privileged_perms()` sprawdza tylko zdolność Efektywną
set (więc przechodzi) i jest **całkowicie pomijany, gdy cel działa jako uid 0**
6. Odcisk palca `VersionExecutable` wywołuje `fpr_kind_executable` za pomocą
`process.command_line[0]` — argv[0] celu, czytany z
`/proc/<pid>/cmdline` i **w pełni kontrolowane przez obciążenie**
7. `fpr_kind_executable` wywołuje `exec.Command(plik wykonywalny, "--wersja").Output()`
— wykonanie **własnego pliku binarnego** obciążenia w jego wierzchołku
przestrzeni nazw, podczas gdy **ruid=0 w przestrzeni nazw użytkownika hosta**
Wykonywany proces może wywołać `setuid(0)` w celu przywrócenia pełnego katalogu głównego
`CAP_SYS_ADMIN` i dziedziczy osierocony cwd, który przekształca się w ekstraktor
system plików kontenera zawierający gniazdo CRI-O hosta.
## Kod, którego dotyczy problem
### 1. Niewystarczający spadek uprawnień (Rust — koordynator ekstraktora)
**Plik:** `extractor/src/insights_runtime_extractor.rs`
„rdza”.
// Linie 139-146 — upuszczenie tylko przez seteuid, ochrona pominięta w przypadku kontenerów root
Join_process_namespaces(proces.pid)?;
zmień_katalog(bieżący_katalog);
switch_user(*proces.uid)?;
if *proces.uid != 0 {
perms::check_no_privileged_perms()
.expect("Nie możesz mieć uprzywilejowanych uprawnień do uruchamiania odcisków palców");
}
odcisk palca::run_fingerprints(&config, out_dir, &process);
```
„rdza”.
// Linie 182-185 — zmieniony został tylko efektywny UID; ruid/suid pobyt 0
fn switch_user(uid: u32) -> Wynik<(), Błąd skanera> {
debug!("... Zostanie użytkownikiem: {uid}");
seteuid(uid.into()).map_err(|e|Błąd skanera::Errno(e))
}
```
### 2. Wykonanie niezaufanego pliku binarnego (Go — odcisk palca)
**Plik:** `fingerprints/pkg/utils/file.go`
idź
// Linie 75–80 — wykonuje ścieżkę pobraną dosłownie z argv[0] obciążenia
func GetExecutableVersionOutput(ciąg wykonywalny) (ciąg, błąd) {
out, err := exec.Command(plik wykonywalny, "--wersja").Output()
jeśli błąd!= zero {
zwróć „”, błąd
}
zwróć ciąg (wyjście), zero
}
```
### 3. Przekazano ścieżkę kontrolowaną przez obciążenie (Rust — wersja_wykonywalna)
**Plik:** `wersja_executable.rs`
„rdza”.
// Linie 29–34 — kontrolowana obciążeniem linia_poleceń[0] przekazywana do odcisku palca
zwróć trochę(vec![
plik wykonywalny fpr_kind_,
out_dir.to_string(),
String::from(&process.command_line[0]),
String::from(&wersja_executable.runtime_kind_name),
]);
```
## Wzór ataku
**Atakujący:** dowolny najemca, który może zaplanować pod (nieuprzywilejowany, dowolna przestrzeń nazw)
**Ofiara:** węzeł, na którym działa zestaw DaemonSet narzędzia do wyodrębniania wniosków
**Trigger:** Automatic — zestaw DaemonSet skanuje wszystkie procesy kontenerowe w węźle
**Sekwencja ataku:**
1. Osoba atakująca tworzy pod, którego nazwa procesu jest zgodna ze skonfigurowaną
wersjonowany wzorzec wykonywalny (`node`, `python`, `python3`, `MainThread`,
lub zawiera `Java`)
2. Główny plik binarny poda (w ścieżce odpowiadającej argv[0]) jest złośliwy
plik wykonywalny, który wywołuje `setuid(0)` w celu przywrócenia roota
3. Gdy operator Insights uruchomi skanowanie, zestaw DaemonSet rozwidla się i wchodzi do
przestrzeń nazw wierzchowca atakującego i wykonuje plik binarny atakującego z ruid=0
4. Kod atakującego odzyskuje pełny root z `CAP_SYS_ADMIN` w użytkowniku hosta
przestrzeń nazw
5. Odziedziczony cwd zawiera gniazdo CRI-O hosta → kompromis pełnego węzła
>_ Słabości (CWE)
>_ Referencje
Dane podatności pochodzą z oficjalnych źródeł (CVE® List / NVD). Opisy po polsku są tłumaczone automatycznie i mogą zawierać nieścisłości – na stronie rekordu można wyświetlić wersję angielską.
This product uses the NVD API but is not endorsed or certified by the NVD.
Copyright © 1999–2026, The MITRE Corporation. CVE is a registered trademark and the CVE logo is a registered trademark of The MITRE Corporation.
CVE Usage: MITRE hereby grants you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Common Vulnerabilities and Exposures (CVE®). Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy. ALL DOCUMENTS AND THE INFORMATION CONTAINED THEREIN PROVIDED BY MITRE ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
NVD Terms of Use / CVE® Terms of Use / nvd.nist.gov / cve.org