최근 수정 시각 : 2024-10-28 19:53:05

xz-utils 백도어 사건



주의. 사건·사고 관련 내용을 설명합니다.

이 문서는 실제로 일어난 사건·사고의 자세한 내용과 설명을 포함하고 있습니다.

1. 개요2. 설명
2.1. xz-utils이란?2.2. 배경
3. 전개
3.1. Jia Tan의 등장3.2. 부계정의 압박3.3. Jia Tan, 큰 힘을 가지게 되다3.4. 본격적인 공격의 시작3.5. 발각
4. 사건 이후5. 여파6. 여담

[clearfix]

1. 개요

CVE-2024-3094
메인 개발자 Lasse Collin의 회고

2024년 3월 29일, 마이크로소프트PostgreSQL 개발자 안드레스 프런드 (Andres Freund)가 리눅스 liblzma 라이브러리 내 xz 버전 5.6.0, 5.6.1에 백도어가 심어져 있음을 발견하여 화제가 된 보안 취약점 사건.

오래된 코드나 개발자의 실수 등으로 발생하는 다른 보안 취약점 사례들과 다르게 해당 백도어를 심은 개발자가 처음부터 악의를 가지고 유일한 개발자에게 접근하여 장장 3년에 걸쳐 빌드업을 쌓다가 백도어를 심은 사건이기 때문에 사실상 범죄에 가까운 보안 취약점이다.

백도어로 인한 피해가 발생하기 이전에 백도어가 심겨진 버전에서 PostgreSQL 테스트 돌려보던 엔지니어가 시스템 자원 사용량에서 이상함을 느껴 발견했다는 꽤나 뽀록에 가까운 발견 정황이 화제가 되기도 했다. 테스트 과정은 보안 문제를 확인하는 것이 목적이 아니라, 단순히 PostgreSQL이 돌아가는 리눅스의 최신 버전에서의 작동을 확인하기 위해서 돌린 것이었다. 만약 이 엔지니어가 이 이상을 대수롭지 않게 넘어갔다면 xz를 업데이트한 모든 리눅스의 대문이 열려버리는 대형 사고가 일어날 뻔 했다.[1]

혼자 중요한 프로젝트를 유지보수하고 있는 개발자가 멘탈 이슈가 있고 번아웃 상태인 것을 노려 소셜 엔지니어링 방법론을 사용하여 접근한 악의적인 보안 취약점 사건으로, 사실상 각 개발자들이 선의 및 취미로 혼자 유지하고 있는 오픈소스 생태계와, 그 위에서 운영되고 있는 너무 거대한 프로그래밍 생태계에 큰 충격을 준 사건이다.

2. 설명

2.1. xz-utils이란?

xz-utils 이란 C언어로 개발된, 개발자 Lasse Collin이 개발한 오픈 소스 CLI 무손실 압축 알고리즘 프로그램이다. Lempel-Ziv-Marakov Chain Algorithm을 사용하기에 LZMA이라고도 불린다.

XZ는 기존 리눅스에서 광범위하게 사용되는 압축 방법인 gzip, bzip2보다 더 높은 압축률을 보여주면서, 커맨드라인으로 접근이 쉽다는 장점이 있었기 때문에 tar 파일 압축, 리눅스 커널 압축 등 특히 리눅스 배포 시 사용되는 압축 플랫폼으로 광범위하게 사용되고 있다.

2.2. 배경

타임라인

xz는 현재 존재하는 많은 리눅스 시스템에서 사용되고 있음에도 불구하고 유지보수는 사실상 최초 개발자인 Lasse Collin이 혼자 담당하고 있었다. [2] 백도어로 화제가 된 이후 2024년 현재는 많은 개발자들이 관심을 가지고 코드 커밋을 하고 있는 것으로 보인다.

Lasse Collin 본인도 본업이 따로 있는 것으로 보이고, xz는 오픈소스로서 취미적인 정도의 개발만을 진행하고 있었던 것으로 보이는데 xz 자체가 너무 인기가 많아 유지보수에 대한 니즈는 계속 있어왔으며, 본인도 계속 해서 그에 대해 압박을 받고 있던 것으로 보인다. 개발자 본인의 응답 중 "이 프로젝트는 돈을 받지 않고 진행하는 오픈소스 취미 프로젝트임을 염두에 두기 바란다", "오랫동안 겪고 있던 정신 건강 이슈 (mental health issues)가 있어 xz에 대한 높은 관심을 유지하기 힘들다"라고 말한 바 있다.

개발자 혼자서 유지보수하고 있고, 모든 리눅스 배포에서 사용되고 있을 정도로 광범위하게 쓰이며, 개발자들이 너무 당연하게(...) 여겨서 관심 밖이었던 해당 프로젝트는 해커의 눈에 띄게 된다.

3. 전개

3.1. Jia Tan의 등장

사실상 Lasse Collin이 독박 개발(...)을 진행하고 있던 와중, 2021년에 계정이 생성된 Jia Tan이라는 계정이 xz-utils의 개발자 목록에 자기 자신을 추가하는 것으로 시작하여, 몇 가지 버그를 고치는 커밋들을 진행했다. 해당 계정은 백도어가 발각된 2024년 3월 이후 활동이 정지된 상태이고 다행히 이 커밋들은 별다른 보안 이슈가 발견되지 않은 진또배기 버그 픽스 커밋이었다고 결론났다.

Lasse Collin 역시 같이 유지보수해주는 개발자의 등장에 어느 정도 안도를 느꼈음에 분명하며, Jia Tan의 커밋을 검토하고 코드에 머지하며[3] Jia Tan은 이렇게 xz-utils에 첫 발을 내딛게 된다.

다만 이 때 Lasse Collin은 Jia Tan이 몇 가지 코드를 커밋해주는 단순 협업 개발자 정도로 생각했으며, 해당 개발자가 메인 코드를 고칠 수 있게끔 하는 메인테이너 (Maintainer) 정도의 권한을 주지는 않았다. 즉, 결국 메인 개발자는 Lasse Collin 본인이었으며, Jia Tan은 몇 가지 코드를 커밋해주는 협업 개발자였다.

3.2. 부계정의 압박

이 때 Jigar Kumar 라는 유저가 Lasse Collin에게 메일을 보내게 된다. 메일의 내용은 'Jia Tan의 패치가 좋아보이는데 반영이 너무 늦다'는 컴플레인이었다. 실제 메일 Lasse Collin은 코드 지연에 대한 사과를 보내며 Jia Tan이 꾸준히 자기 자신에게 도움을 주고 있고, 후에 그에게 더 많은 역할을 부여할 수 있을거라는 메일을 보냈다.

이에 설상가상으로 Dennis Ens라는 유저가 등장하여 Lasse Collin에게 Java 버전 XZ가 유지보수가 되고 있냐는 메일을 보냈다. 단순 질문이지만, 위 내용들의 메일은 누구나 열어볼 수 있음을 감안하면 Dennis Ens 또한 Lasse Collin에게 압박을 넣은 것이다. 위 메일들은 xz 개발자들에게 보내는 메일로서, 스레드 처럼 작용하여 mail-archive이라는 사이트에서 열어볼 수 있다.

허나 이후에도 이 Jigar Kumar이라는 유저는 Lasse Collin에게 '이 속도면은 올해 안에 5.4.0 못 나오겠네. 여태 테스트 코드만 돌리고 앉았잖아. 너가 지금 이 레포의 목을 조르고 있는거야. (Right now you choke your repo)' 라고 하는 등 상당히 압박을 주는 과격한 워딩들을 사용했으며, Lasse Collin 역시 답장에서 자기 자신의 멘탈 이슈[4] 등을 밝히며 코드 지연에 대해 사과 답변을 보냈다.

이 때 다시금 Dennis Ens라는 유저가 Lasse Collin에게 메일을 보내며 '멘탈 이슈가 있는건 알겠는데, 자기 자신의 한계는 알아야지. 이거 취미 프로젝트인건 알겠지만 커뮤니티는 이미 더 원하고 있어. 또 다른 개발자에게 Maintainer를 넘기는 것은 어때?' 라며 한 술 더 뜨는 메일을 보내게 된다. 해당 메일

이후에도 계속 Jigar Kumar는 'Jia Tan 커밋 쌓인거 보이는데 이거 언제 처리할래?' 등의 이메일로 Lasse Collin에게 압박을 넣었다.

계속 되는 유저들의 압박에 못 이긴 Lasse Collin은 기존에 이미 답변했던 Jia Tan의 추가 역할 부여 가능성을 언급하며 'Jia Tan은 이미 코드에 많은 도움을 줬고, 사실상 현재 공동 메인테이너나 다름없으니까, 후에 메인테이너 변경을 고려해볼게'라면서 사실상 Jia Tan의 메인테이너 승격을 암시했다.

위 압박 과정은 해킹 사건의 주범인 Jia Tan에게 큰 권한을 주게 되는 계기가 되었으며, 사실상 해킹 사건의 초석이 되었다.

이 과정이 중요한 이유는 위 과정에서 주요한 역할을 한 Jigar Kumar, Dennis Ens라는 계정이 가계정 의혹이 있기 때문이다.Brian Krebs의 코멘트 위 두 계정은 인터넷에서의 흔적이 전혀 없으며, GitHub이나 GitLab에서도 흔적이 없는 소위 갑툭튀한 계정이기 때문이다. 위 과정을 통해 Jia Tan이 강력한 Maintainer라는 권한[5]을 갖게 되었기 때문에, 사실상 Jia Tan과 동일인인 것으로 파악되고 있다.

3.3. Jia Tan, 큰 힘을 가지게 되다

이후 Jia Tan은 xz-utils에 대해 Maintainer에 준하는 권한을 얻게 되었으며, 2022년 12월 30일에는 자신의 코드를 직접 메인 브랜치에 커밋하게 될 정도로 강력한 권한을 뽐내게 되었다. 허나 Jia Tan이 권한을 가지게 된 이후에도 코드를 자기 멋대로 작업하게 되면 Lasse Collin이 이상함을 감지할 수 있으므로, Jia Tan이 책임감 있는, 신뢰할만한 Maintainer로서 역할하는 것을 보여주어 Lasse Collin에게서 신뢰를 얻어야 할 필요성이 있었다.

이를 위해 Jia Tan은 Maintainer로서 강력한 기능이라고 할 수 있는 코드 직접 반영을 하기 이전, 문제가 없는 버전인 5.4.0 버전의 Release Summary를 작성하였다.[6] 또한 그 이전에는 Tukaani Project라는 사실상 Lasse Collin의 개인 홈페이지에 구축된 Git에서 xz-utils가 관리되고 있었으나, Jia Tan이 공동 Maintainer가 되었으므로 이를 용이하게 유지하기 위해 GitHub으로 프로젝트를 옮길 준비를 하게 된다.[7]

이 과정에서 Lasse Collin은 이제 같이 xz-utils를 작업할 Jia Tan의 존재가 생겼으므로 버그 리포트 이메일 목록에 Jia Tan을 추가하였으며, 5.4.1까지는 자기 자신이 작업하여 배포하였지만, 5.4.2부터는 Jia Tan이 직접 배포할 수 있도록 하게 한다.

허나 이 와중에도 Jia Tan은 백도어 공격을 위해 밑작업을 하는 것을 잊지 않았다. 가장 먼저 xz-utils의 버그 발생 시 Google에도 버그 제보를 할 수 있도록 oss-fuzz를 설정하는 과정에서 기존 Lasse Collin 대신 자기 자신에게 1차적으로 컨택할 수 있도록 연락처를 변경하였으며, Hans Jensen[8]의 겉보기로는 멀쩡해보이는 코드 수정을 반영하고[9], 상술한 Google 관련 작업에서 호환성이 맞지 않는다는 핑계로 ifunc 지원[10]을 제거했다.

이후 Jia Tan은 미리 준비해뒀던 GitHub으로의 코드 이전을 완료하였으며, Lasse Collin 역시 원래 자기 자신의 Git 페이지로 연결되었던 xz-utils 페이지를 GitHub의 페이지로 돌렸다. [11] 이것이 2024년 1월 19일이었다.

3.4. 본격적인 공격의 시작

공격의 기반을 닦은 Jia Tan은 2024년 2월 23일 테스트 코드 바이너리에 난독화된 백도어 코드를 심음으로서 공격을 개시한다. Jia Tan 등장 이전에도 README에서 '테스트 폴더에는 소스코드란 존재하지 않으며, xz 테스트를 위한 단순 파일들뿐이다'라고 쓰여있을 정도로 해당 폴더는 감시가 소홀했으며, Jia Tan은 이 부분을 이용했다.

Jia Tan은 5.6.0 배포를 준비하면서 Debian 또는 Fedora 등 모든 리눅스에서의 배포에서 추가되는 build-to-host.m4라는 악의적 코드를 배포에 추가하였다. 이 코드는 xz-utils 본 레포에는 존재하지 않고, 각 리눅스 배포 시 실행되는 코드로, 즉 패키지 빌드 시에 실행되어 테스트 폴더에 있는 백도어 바이너리를 실행시키는 코드였다.자세한 실행 원리

이 때 리눅스 커널에는 Landlock Detection이라는 원치 않은 권한 부여를 방지하는 감지 코드가 존재하는데, Jia Tan은 이 코드에 미묘한 오타를 추가함으로써 사실상 Landlock Detection을 무력화시켰다.

이 때, 5.6.0에서는 상술한 ifunc 관련 작업의 여파로 Valgrind[12]에서 오류가 발생하였다. Jia Tan은 이를 고친 5.6.1을 배포하였다. 5.6.0, 5.6.1 모두 백도어 코드가 들어있는 상태였다. 이 때 5.6.0은 Arch Linux, Fedora 등에 반영되어 있었다.

이 때 위에서 등장한 Hans Jansen이라는 가계정이 등장하여, Debian에 버그 픽스로 인해 xz의 5.6.1 업데이트를 권장하는 글을 올렸다.

5.6.0을 포함한 테스트 빌드에서 버그가 발생한 것은 확실했으므로, Debian은 백도어가 심어져 있는 5.6.1을 자신들의 배포에 추가하게 된다.

이대로 배포만 진행되면 Jia Tan의 공격은 성공으로 끝나는 것이었다.

3.5. 발각

마이크로소프트에서 근무하는 PostgreSQL 개발자 안드레스 프런드는 2024년 3월 28일, 여느 날과 같이 PostgreSQL 테스트를 위해 SSH를 통해 원격 접속을 진행중이었다.

허나 이상하게도 몇몇 시스템에 접속할 때 접속 지연이 발생하는 것을 확인했다. 해당 지연은 약 500ms (0.5초) 정도였다.

이에 대해 궁금증을 가진 Andres Freund는 조사 결과 xz-utils가 SSH에 영향을 주어 시스템 사용량을 증가시킨 것을 확인했다.[13]

처음에는 백도어라고 생각하지 않고 단순 버그라고 생각했기 때문에 조용히 버그 제보를 진행했고, Debian 등은 이에 반응하여 5.6.1을 이상이 있었던 버전의 전인 5.4.5 버전으로 롤백하게 된다. [14]

이후 Andres Freund는 추가적인 조사를 진행하여, xz에 백도어가 심어졌다고 판단, OpenWall에 공개적으로 제보하게 된다. 백도어 제보자의 제보 글 이것이 2024년 3월 29일이었다.

2024년 3월 30일, xz-utils의 원래 개발자 Lasse Collin은 공식적으로 프로젝트에 백도어가 심어졌음을 발표했으며, Jia Tan을 즉각적으로 메일링에서 제외하였음을 알렸고, 버전은 5.8.0으로 점프해서 배포할 것임을 알렸다.

4. 사건 이후

해킹에 쓰일뻔한 레포지토리이기 때문에 xz-utils는 GitHub에서 잠시 내려갔고, 4월 9일 다시 복구가 완료되었다.

Jia Tan과 Lasse Collin의 깃헙 계정 역시 정지되었고, Lasse Collin의 계정은 4월 2일에 다시 복구가 되었다.

롤백 이후 최초의 깔끔한 버전 업그레이드는 2024년 5월 29일에 진행되었다.

5. 여파

다행히 한국에서는 5.6.0, 5.6.1 버전이 포함된 리눅스로의 버전 업그레이드를 한 경우가 별로 없어 따로 제보가 없었다고 한다.보안뉴스

xz --version

리눅스 사용자들은 현재 xz 버전을 확인하여, 5.6.0이거나 5.6.1인 경우 xz 업데이트를 진행하거나 백도어가 없는 버전인 5.4.x 버전으로 다운그레이드를 진행해야한다.

기존 해킹 사건들은 일부러 오타를 내는 타이포스콰팅 (Typosquatting) 등 단편적인 기법만 사용했던 반면에 해당 사건은 장장 3년에 걸친 빌드업을 진행하는 등 치밀함이 있어 개인이 아닌 국가 또는 해킹 단체의 소행으로 추측하는 의견이 많다. 또한 백도어 바이너리의 암호화 수준이나 백도어를 실행하는 코드를 소스 코드가 아닌 패키지 빌드 (Tarball)에 넣어 진행하는 등 해킹 지식의 수준이 높아 충격을 주었다.

해당 사건으로 인해 개인이 유지하고 있는 오픈소스 레포와 그에 의존하는 커뮤니티에 대해 재고해보는 시간을 가지게 되었으며, 개인의 선의 또는 취미로 운영되는 많은 오픈소스 프로젝트에 대한 관심이 촉구되었다.

6. 여담

  • xz-utils의 개발자 Lasse Collin은 이후 후원에 관련한 많은 문의를 받았으나, 핀란드 법에 의하면 개인이 후원을 받고 아무것도 돌려주지 않는 것은 불법이기 때문에 후원을 열지 못 한다고 밝혔다.
  • 해당 해킹의 주범 Jia Tan은 신뢰를 쌓기 위함인지 xz-utils 외에도 유닛 테스트 레포지토리 등을 추가하는 등 선의의 개발자 코스프레를 위해 노력했음이 보인다.
  • Libarchive 등에도 Jia Tan이 커밋한 흔적이 있어 관련 개발자들이 커밋을 재검토하는 등 생고생을 했다.
  • 현재도 Jia Tan의 커밋이나 Pull Request 자체는 살아있는데, 찾아 가보면 많은 개발자들의 비꼬는 코멘트와 비추 폭탄(...)이 달려있다.

[1] 처음에는 SSH 인증을 우회하는 백도어로 파악했으나, 추가 조사 결과 원격 코드 실행 (RCE)이 가능한 백도어인 것으로 확인되었다.[2] xz 자체는 2005년에 처음 개발되었으며, 개발 당시에는 Lasse Collin뿐만 아니라 여러 개발자가 협업하였던 것으로 보인다. 이 때 협업한 개발자 중 하나는 7-Zip의 개발자인 Igor Pavlov이다.[3] Git 구조에서 커밋은 개발자 누구나 할 수 있는 '이렇게 코드를 고치면 좋겠습니다' 정도의 제안이며, 이를 메인 브랜치에 머지(통합)하게 되면 본격적으로 프로그램으로 편입된다고 생각하면 된다.[4] 배경에 서술되어있는 Lasse Collin의 멘탈 이슈는 이 메일에서 밝혀졌다.[5] Maintainer는 해당 코드 레포지토리에 대한 권한을 가져 별도의 검토 없이 자신의 코드를 메인 브랜치에 머지할 수 있게 된다.[6] 이 과정은 버전 릴리즈에 대한 Lasse Collin의 부담감을 낮춰줌과 동시에 자기 자신 또한 해당 레포의 책임자라는 것에 대한 선언과 비슷하다.[7] 물론 많은 오픈소스 프로젝트가 GitHub에서 관리되고 있으므로 이는 전혀 이상한 작업이 아니며, 백도어 발각 이후에도 xz-utils은 GitHub에서 작업을 진행하고 있다. 단 이 과정이 중요한 이유는 기존에는 xz-utils이 사실상 Lasse Collin의 개인 프로젝트였고 Git이 올라가는 페이지 또한 Lasse Collin의 페이지였기 때문에, 이를 GitHub으로 옮기면 Lasse Collin의 권한이 줄어드는 효과가 있었기 때문이다.[8] xz-utils 관련 작업에만 나타나고 기타 인터넷에 전혀 흔적이 없어 역시 Jia Tan의 부계정 의혹이 있다.[9] 이 역시 백도어 진행 과정에서 주요한 역할을 했다. 허나 그 자체로는 단순 성능 개선 작업일 가능성이 있어 Lasse Collin도 해당 코드를 최종적으로 수정한 후 반영했다.[10] 이 역시 백도어의 주요 기반으로 작용했다[11] 백도어 발각 이후 다시 원래대로 복원했다.[12] 해당 백도어를 발견하게 된 툴로, 메모리 누수 등을 발견할 수 있는 디버깅 툴이다.[13] Valgrind를 확인하여 SSH의 CPU 사용량이 과도하게 많았음을 확인했다고 한다.[14] 이 때 최초로 해당 사건에 CVE-2024-3094라는 보안 취약점 코드가 부여되었다.