Pexels photo 17489152

트러스팅 트러스트 공격 총정리 — 컴파일러가 리눅스 배포판 전체를 뚫는 원리와 2026년 방어법

📌 핵심 요약컴파일러 백도어가 리눅스 배포판 전체를 오염시키는 원리와 2026년 방어 스택 3층, 실행 체크리스트 5단계를 총정리했습니다. 재현 가능한 빌드부터 무료 서명 도구까지 지금 바로 비교해보세요. 소스만 감사하면 안전하다는 착각, 모르면 손해입니다.

컴파일러를 믿는다는 것의 진짜 비용

1984년 켄 톰프슨은 튜링상 수상 강연 「Reflections on Trusting Trust」에서 지금까지도 완전히 닫히지 않은 구멍을 공개했습니다. 논리는 3단이고, 각 단계는 그 자체로 평범합니다.

1. 컴파일러가 login 소스를 컴파일할 때를 감지해 백도어를 심는다.
2. 컴파일러가 자기 자신의 소스를 컴파일할 때를 감지해, 1번 기능을 다시 심는다.
3. 이제 컴파일러 소스에서 악성 코드를 전부 지워도, 그 소스를 기존 바이너리로 빌드하는 한 백도어는 계속 살아난다.

소스 코드를 100% 감사해도, 그 소스를 기계어로 바꾼 도구가 오염돼 있으면 감사는 아무것도 증명하지 못합니다.

왜 “리눅스 배포판 전체”로 번지는가

배포판의 빌드 체인은 원형입니다. GCC는 GCC로 빌드하고, glibc·binutils·make·bash는 서로를 필요로 합니다. 이 순환 어딘가에 한 번 오염이 들어가면, 그 배포판에서 소스로부터 다시 빌드해도 오염이 씻기지 않습니다. 재빌드가 오염된 도구를 다시 쓰기 때문입니다. 공격 표면이 패키지 하나가 아니라 “그 배포판으로 만든 모든 바이너리”가 되는 이유가 여기 있습니다.

실증은 공격이 아니라 검증 쪽에서 축적됐다

그래서 방어의 무게중심도 “뚫는 실험”보다 “뚫렸는지 판별하는 실험” 쪽에 놓입니다.

1. Diverse Double-Compiling (DDC)

데이비드 휠러가 정식화한 기법입니다. 검증 대상 컴파일러의 소스를 완전히 다른 계보의 두 번째 컴파일러로 한 번 빌드하고, 그 결과물로 다시 원본 소스를 빌드해 산출물을 비교합니다. 두 컴파일러가 동시에 같은 방식으로 오염돼 있지 않은 한 불일치가 드러납니다. 휠러는 이 절차를 실제 컴파일러(tcc, GCC)에 적용해 검증 가능함을 보였습니다.

2. 재현 가능한 빌드(Reproducible Builds)

같은 소스에서 누가 빌드해도 비트 단위로 동일한 산출물이 나오게 만드는 프로젝트입니다. 데비안이 주도했고 지금은 Arch, Fedora, openSUSE, F-Droid 등으로 퍼졌습니다. diffoscope가 차이를 사람이 읽을 수 있게 풀어주고, rebuilderd가 독립 재빌드를 자동으로 돌려 공식 바이너리와 대조합니다. DDC의 전제를 대규모로 깔아 주는 인프라입니다.

3. 부트스트랩 가능성(Bootstrappability)

GNU Guix는 신뢰해야 할 이진 시드 자체를 극단적으로 줄이는 “full-source bootstrap”을 2023년에 공개했습니다. 사람이 검토 불가능한 거대한 바이너리에서 출발하지 않고, 아주 작은 시드에서 어셈블러 → C 컴파일러 → GCC 순으로 쌓아 올리는 방향입니다. 톰프슨 공격의 은신처를 물리적으로 좁히는 접근입니다.

XZ 백도어(CVE-2024-3094)가 바꾼 관점

2024년 3월 공개된 xz-utils 백도어는 순수한 트러스팅 트러스트 공격은 아닙니다. 하지만 git 저장소에는 없고 배포 tarball에만 존재하는 빌드 스크립트 조각을 통해 들어왔다는 점에서, “소스는 봤다”가 왜 충분하지 않은지를 실전에서 증명했습니다.

> 실무 교훈은 단순합니다. 릴리스 tarball을 그대로 믿지 말고, git 태그에서 체크아웃해 autoreconf로 빌드 스크립트를 직접 재생성한 뒤 빌드하십시오.

2026년 현실적인 방어 스택 3층

도구·서비스 담당 층 비용 형태 추천 대상 구매 포인트
diffoscope + rebuilderd 재현 빌드 검증 오픈소스, 무료 패키지 메인테이너, 배포 담당 도입 비용 0. 재현성 실패 원인을 파일 단위로 보여줘 첫 단계로 적합
GNU Guix / NixOS 부트스트랩·격리 빌드 오픈소스, 무료 빌드 재현성이 요건인 연구·인프라 팀 학습 곡선이 가파르므로 CI 빌더 한 대부터 시범 적용
Sigstore cosign + Rekor 서명·투명성 로그 오픈소스, 무료 컨테이너 이미지를 배포하는 팀 키 관리 없이 OIDC 기반 서명 가능. 가성비 관점에서 우선순위 최상
SLSA provenance (GitHub Actions) 출처 증명 요금·플랜은 GitHub 공식 문서 확인 이미 GitHub CI를 쓰는 팀 워크플로 추가만으로 프로버넌스 생성. 기존 파이프라인 변경 최소
Chainguard Images (Wolfi 기반) 최소 베이스 이미지 공개 이미지와 상용 카탈로그가 나뉨(범위는 공식 페이지 확인) 규제 대응·SBOM 제출이 필요한 조직 과거 태그·SLA 제공 범위와 요금은 공식 페이지에서 확인형이므로 견적 필수
Syft + Grype, Trivy SBOM·취약점 스캔 오픈소스, 무료 소규모 팀 전체 무료 도구만으로 SBOM 생성까지 커버. 상용 SCA 도입 전 검증용으로 적합
YubiKey 5 시리즈 / YubiHSM 2 서명키 하드웨어 보관 하드웨어 1회 구매(공식 스토어 가격 확인) 릴리스 서명 권한을 가진 담당자 개인키가 CI 서버 디스크에 남는 구조라면 필요. 분실 대비 2개 구매 후 백업 등록이 원칙

이번 주에 할 수 있는 5단계

1. 빌드 입력을 고정한다 — 릴리스 tarball 대신 git 태그 + 커밋 해시로 소스를 고정합니다.
2. 빌드를 두 번 돌린다 — 서로 다른 머신·다른 시각에 빌드해 해시를 비교합니다. 여기서 깨지면 재현성이 아직 없는 것입니다.
3. 비결정 요소를 제거한다 — 타임스탬프(SOURCE_DATE_EPOCH), 빌드 경로, 파일 순서, 로케일이 흔한 원인입니다.
4. 산출물에 서명과 프로버넌스를 붙인다 — cosign 서명과 SLSA 프로버넌스를 릴리스 아티팩트에 함께 게시합니다.
5. 검증을 소비자 쪽에도 강제한다 — 배포 파이프라인에서 서명 검증 실패 시 배포가 멈추도록 게이트를 겁니다.

결론 — 가장 추천하는 조합

개인 개발자와 소규모 팀에 가장 추천하는 조합은 cosign(서명) + GitHub Actions SLSA 프로버넌스(출처) + diffoscope(재현성 확인) 세 가지입니다. 셋 다 무료이고, 기존 CI에 얹는 방식이라 파이프라인을 갈아엎지 않아도 됩니다. 여기에 릴리스 서명 키를 하드웨어로 옮겨야 하는 단계가 오면 YubiKey 계열을, 규제 산업에서 베이스 이미지 출처까지 문서화해야 한다면 Chainguard 같은 상용 구독을 검토하는 순서가 합리적입니다.

트러스팅 트러스트는 완전히 “해결”되는 문제가 아니라, 신뢰해야 하는 이진 덩어리의 크기를 계속 줄여 나가는 문제입니다. 재현 가능한 빌드는 그 크기를 줄이는 가장 저렴한 수단입니다.

참고 자료

Ken Thompson, Reflections on Trusting Trust (CACM, 1984)
David A. Wheeler, Countering Trusting Trust through Diverse Double-Compiling
Reproducible Builds 프로젝트
GNU Guix, The Full-Source Bootstrap

자주 묻는 질문

소스 코드를 전부 감사하면 트러스팅 트러스트 공격을 막을 수 있나요?

막을 수 없습니다. 공격은 소스가 아니라 소스를 기계어로 바꾸는 컴파일러 바이너리에 숨어 있고, 컴파일러 소스에서 악성 코드를 지워도 오염된 바이너리가 재빌드 때 다시 심습니다. 소스 감사와 별개로 빌드 산출물의 재현성 검증이 필요합니다.

재현 가능한 빌드(Reproducible Builds)만 하면 안전한가요?

재현 가능한 빌드는 ‘내가 빌드한 결과와 공식 배포본이 같은가’를 확인해 주지만, 모두가 같은 오염된 컴파일러를 쓰면 결과도 똑같이 오염된 채 일치합니다. 그래서 계보가 다른 컴파일러로 교차 검증하는 DDC나 부트스트랩 시드 축소가 함께 필요합니다.

XZ 백도어 사건은 트러스팅 트러스트 공격과 같은 유형인가요?

엄밀히는 다릅니다. XZ 백도어(CVE-2024-3094)는 컴파일러 자체가 아니라 배포 tarball의 빌드 스크립트에 코드가 들어간 사례입니다. 다만 ‘공개된 소스만 봐서는 발견할 수 없다’는 구조적 약점을 공유하며, git 태그에서 빌드 스크립트를 재생성해 빌드하는 습관으로 완화할 수 있습니다.

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다