FlawOpen

flawopen.com/Incidents/xz-utils-backdoor-march-2024

● Xz · CVE-2024-3094 · March 2024 · CVSS 10.0 · 심각
보안 연구 · FlawOpen

XZ Utils 공급망 침해 (CVE-2024-3094)

CVE-2024-3094는 XZ Utils 5.6.0/5.6.1에 영향을 주었습니다. 위험은 배포판 빌드 조건에 따라 달랐으므로 해당 패키지를 찾아 교체하세요.[1], [3], [4], [5], [6]

CVSS 벡터CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H[9]
💡 알기 쉬운 설명 (ELI5)

소스 저장소를 공개된 조리법, 릴리스 아카이브를 밀봉된 식재료 상자라고 생각해 보세요. 조리법이 맞아 보여도 주방은 상자의 봉인과 납품서를 확인합니다. 같은 음식 이름이 적혀 있다는 이유만으로 상자를 곧바로 조리대에 올려놓아서는 안 됩니다. 별도의 신뢰 채널로 인증한 매니페스트는 바뀐 상자를 찾아낼 수 있지만, 유효한 공급업체 서명도 승인된 상자가 안전하다는 점까지 증명하지는 못합니다. 침해된 XZ 상자도 공식 릴리스였습니다. 배포판 안내에 따라 영향받은 패키지를 교체하고, 매니페스트 검증은 바꿔치기를 막는 별도 통제로만 사용하세요.[5], [6]

핵심 개념 및 용어

릴리스 아카이브
설치나 패키징을 위해 배포하는 소스 코드 묶음입니다. 저장소에서 받은 파일과 다를 수 있으므로 별도의 산출물로 검증해야 합니다.[3], [4], [6]
빌드 출처 증명(build provenance)
산출물이 어떤 검토된 소스, 빌드 단계, 게시자에서 왔는지 기록한 증거입니다. 다운로드한 파일을 신뢰할지 판단하게 해 줍니다.[5], [6]
산출물 검증(artifact verification)
산출물을 빌드나 릴리스에 사용하기 전에 해시나 서명을 독립적인 신뢰 경로로 얻은 기대값과 대조하는 절차입니다.

프레임워크 매핑

  • 이 가이드에서 설명하는 약점의 CWE 참조: CWE-506

사고 타임라인

2024년 2월 24일

XZ 5.6.0이 릴리스되었습니다. 프로젝트의 후속 설명에 따르면 해당 릴리스 아카이브에는 백도어가 포함되었습니다.[3], [6]

2024년 3월 9일

XZ 5.6.1이 릴리스되었습니다. 같은 설명에 따르면 해당 릴리스 아카이브에도 백도어가 포함되었습니다.[4], [6]

2024년 3월 29일 전

비정상적인 SSH CPU 사용량과 Valgrind 오류가 조사를 촉발한 뒤, Freund는 배포 아카이브에는 있으나 해당 업스트림 소스 파일에는 없는 주입된 빌드 스크립트를 보고했습니다.[5], [6]

2024년 3월 29일

Andres Freund가 문제를 공개적으로 보고했습니다.[5]

단계별 공격 실행 흐름

단계 1

저장소와 배포물은 같지 않다

공개 분석에 따르면 배포 아카이브에는 해당 업스트림 저장소 파일과 다른 빌드 스크립트 변경이 있었습니다. 저장소 커밋만 검토해서는 아카이브의 안전성을 증명할 수 없습니다.[5], [6]

단계 2

영향은 빌드 경로에 의존한다

이 문제는 특정 패키징과 빌드 조건에서 나타났습니다. 공식 보고서는 Git에서 빌드하면 관련 코드가 주입되지 않는다고 설명하므로, 모든 XZ 또는 Linux 설치로 일반화해서는 안 됩니다.[5], [6]

단계 3

이상 징후가 조사의 출발점이 됐다

Andres Freund는 SSH 프로세스의 비정상적인 CPU 사용량과 Valgrind 오류를 보고했습니다. 관찰 가능한 이상 징후가 조사와 공개로 이어졌습니다.[5]

단계 4

대응은 교체와 검증에서 시작한다

이 문제를 영향받은 패키지와 빌드 출처에 관한 사고로 다루세요. 배포판 안내에 따라 영향받은 패키지를 교체하세요. 향후 아티팩트의 출처와 서명을 검증하면 바꿔치기를 찾을 수 있지만, 승인된 릴리스 자체가 무해하다는 점까지 입증하지는 못합니다.[1], [6]

소스 코드 비교: 취약한 구현 vs 보안 패치

취약한 구현
# 다운로드한 빌드 입력을 그 신원을 증명하지 않고 받아들인다.
from pathlib import Path

def stage_release(artifact: Path, build_inputs: Path) -> None:
    build_inputs.joinpath(artifact.name).write_bytes(artifact.read_bytes())

# 복사가 성공해도 이 아카이브가 검토된 릴리스 또는
# 신뢰할 수 있는 매니페스트에 해당한다는 증거는 아니다.
보안 강화 패치
# 교육용 게이트: 신뢰할 수 있는 매니페스트의 예상 SHA-256을 검증한다.
import hashlib
import hmac
from pathlib import Path

def verify_release(artifact: Path, expected_sha256: str) -> None:
    digest = hashlib.sha256(artifact.read_bytes()).hexdigest()
    if not hmac.compare_digest(digest, expected_sha256.lower()):
        raise ValueError("릴리스 산출물이 신뢰할 수 있는 매니페스트와 일치하지 않습니다")

# expected_sha256은 별도로 인증된 게시 경로에서 구하고,
# 아카이브를 빌드 입력으로 사용하기 전에 verify_release를 호출한다.

# 이는 바꿔치기를 찾지만 승인된 악성 릴리스는 찾지 못합니다. 영향받은 패키지는 공급업체 안내를 따르세요.

엔지니어링 및 시스템 보안 강화 체크리스트

출처