Kestrel
대시보드로 돌아가기
CVE-2026-104795HIGH· 8.8MITRENVD대응게시일: 2026. 10. 14.수정일: 2026. 10. 15.CNA: secalert@redhat.comAwaiting Analysis

The insights-runtime-extractor runs as a privileged DaemonSet (`hostPID: true`) that scans container processes for runtime fingerprinting. W

Privilege-Escalation

위협 신호 · CVSS · EPSS · KEV

정기 패치· 높은 악용 신호 없음
CVSS
8.8high

이론적 심각도 점수

EPSS
0.2%상위 94.7%

30일 내 악용 확률 예측

KEV
미등재

실측 악용 기록 없음

권장 대응 기한차기 업그레이드 시CISA SSVC 기준

별도 긴급 패치 불필요 — 정기 시스템 업그레이드 주기에 맞춰 조치

완전 장악· KEV 미등재 · 자동화 어려움 · 완전 장악 · 내부 한정

CVSS 벡터 · 메트릭

악용 경로
공격 벡터로컬
공격 복잡도낮음
필요 권한낮음
사용자 상호작용불필요
범위변경
영향
기밀성 영향높음
무결성 영향높음
가용성 영향높음
버전별 점수
CVSS 3.18.8HIGH· 악용성 2· 영향도 6
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

약점 (CWE)

상세 설명

The insights-runtime-extractor runs as a privileged DaemonSet (hostPID: true)
that scans container processes for runtime fingerprinting. When scanning a
container, the coordinator:

  1. fork()s a child process
  2. setns() into the target container's PID and mount namespaces
  3. fchdir() back to an orphaned FD pointing at the extractor's own root
    filesystem (where /crio.sock is hostPath-mounted)
  4. Calls only seteuid(target_uid) — changing the effective UID but leaving
    the real UID and saved-set-UID at 0 and retaining the permitted
    capability set
  5. The check_no_privileged_perms() guard inspects only the Effective capability
    set (so it passes), and is skipped entirely when the target runs as uid 0
  6. The VersionExecutable fingerprint invokes fpr_kind_executable with
    process.command_line[0] — the target's argv[0], read from
    /proc/<pid>/cmdline and fully controlled by the workload
  7. fpr_kind_executable calls exec.Command(executable, "--version").Output()
    — executing the workload's own binary inside the workload's mount
    namespace while ruid=0 in the host user namespace

The executed process can call setuid(0) to restore full root with
CAP_SYS_ADMIN, and inherits the orphaned cwd which resolves into the extractor
container's filesystem containing the host CRI-O socket.

Affected Code

1. Insufficient privilege drop (Rust — extractor coordinator)

File: extractor/src/insights_runtime_extractor.rs

text
1// Lines 139-146 — seteuid-only drop, guard skipped for root containers
2join_process_namespaces(process.pid)?;
3change_dir(current_dir);
4switch_user(*process.uid)?;
5if *process.uid != 0 {
6 perms::check_no_privileged_perms()
7 .expect("Must not have privileged permissions to run fingerprints");
8}
9fingerprint::run_fingerprints(&config, out_dir, &process);
text
1// Lines 182-185 — only effective UID changed; ruid/suid stay 0
2fn switch_user(uid: u32) -> Result<(), ScannerError> {
3 debug!("... Becoming user: {uid}");
4 seteuid(uid.into()).map_err(|e| ScannerError::Errno(e))
5}

2. Execution of untrusted binary (Go — fingerprint)

File: fingerprints/pkg/utils/file.go

text
1// Lines 75-80 — executes a path taken verbatim from workload's argv[0]
2func GetExecutableVersionOutput(executable string) (string, error) {
3 out, err := exec.Command(executable, "--version").Output()
4 if err != nil {
5 return "", err
6 }
7 return string(out), nil
8}

3. Workload-controlled path forwarded (Rust — version_executable)

File: version_executable.rs

text
1// Lines 29-34 — workload-controlled command_line[0] forwarded to fingerprint
2return Some(vec![
3 fpr_kind_executable,
4 out_dir.to_string(),
5 String::from(&process.command_line[0]),
6 String::from(&version_executable.runtime_kind_name),
7]);

Attack Pattern

Attacker: Any tenant able to schedule a pod (unprivileged, any namespace)
Victim: The node running the insights-runtime-extractor DaemonSet
Trigger: Automatic — the DaemonSet scans all container processes on the node

Attack sequence:

  1. Attacker creates a pod whose process name matches a configured
    versioned-executable pattern (node, python, python3, MainThread,
    or contains java)
  2. The pod's main binary (at the path matching argv[0]) is a malicious
    executable that calls setuid(0) to restore root
  3. When the insights operator triggers a scan, the DaemonSet forks, enters the
    attacker's mount namespace, and executes the attacker's binary with ruid=0
  4. The attacker's code regains full root with CAP_SYS_ADMIN in the host user
    namespace
  5. The inherited cwd contains the host CRI-O socket → full node compromise

AI 심층 분석

공격 시나리오 · 재현 가능한 PoC 페이로드 · 즉시 적용 가능한 차단 패치를 한 번에 받아 보세요. 보안 운영팀이 그대로 점검·티켓팅에 쓸 수 있는 형태로 정리해 드립니다.