2P by GN⁺ | ★ favorite | 댓글 1개
  • XZ Utils/liblzma 백도어는 2024년 3월 29일 Openwall OSS-security 메일링 리스트에서 공개됐으며, systemd 기반 배포판의 OpenSSH 서버 sshd에 원격 코드 실행 능력을 심는 것이 공격자의 최종 목표였을 가능성이 큼
  • 감염 체인은 XZ 저장소의 테스트 파일과 빌드 인프라를 이용한 다단계 삽입으로 구성됐고, build-to-host.m4, bad-3-corrupt_lzma2.xz, good-large_compressed.lzma를 거쳐 악성 오브젝트 파일이 빌드 중 liblzma에 링크됨
  • 백도어가 포함된 XZ 5.6.0과 5.6.1은 일부 주요 벤더의 베타·실험 빌드로 배포됐고, CVE-2024-3094는 심각도 10점으로 지정됨
  • 바이너리 백도어는 GLIBC의 IFUNCcpuid 호출 경로를 악용해 로딩되며, 이후 OpenSSL/libcrypto 관련 함수를 후킹해 감염된 머신의 연결을 감시하려 함
  • 악성 코드는 /usr/bin/sshd 실행 여부와 킬 스위치 환경변수를 확인하고, trie 기반 문자열 처리·동적 심볼 해석·rtdl-audit 런타임 패치로 분석과 탐지를 어렵게 만듦

사건 개요와 영향 범위

  • 2024년 3월 29일 Openwall OSS-security 메일링 리스트의 메시지를 통해 XZ 백도어 발견이 공개됨
  • XZ는 여러 주요 Linux 배포판에 통합된 압축 유틸리티
  • 위험의 핵심은 백도어가 포함된 liblzma가 일부 systemd 기반 배포판에서 OpenSSH 서버 프로세스 sshd와 연결될 수 있다는 점임
    • Ubuntu, Debian, RedHat/Fedora Linux는 OpenSSH가 systemd 기능을 사용하도록 패치되어 이 라이브러리에 의존함
    • Arch Linux와 Gentoo는 영향받지 않는 것으로 정리됨
  • 공격자의 최종 목표는 다른 사람이 사용할 수 없는 sshd 원격 코드 실행 기능을 넣는 것이었을 가능성이 큼
  • 단일 악성 패치, 가짜 패키지, 타이포스쿼팅 패키지 중심의 다른 공급망 공격과 달리, 이 사건은 전 세계 SSH 서버 침해에 거의 성공할 뻔한 다단계 작전에 가까움

백도어가 들어간 방식

  • liblzma 백도어는 빌드 과정과 테스트 파일을 함께 이용해 두 수준에서 삽입됨
    • 최종 패키지를 생성하는 빌드 인프라 소스 코드build-to-host.m4 추가로 수정됨
    • 테스트 케이스 파일 안에 숨겨진 스크립트와 바이너리 구성요소가 빌드 중 추출됨
  • 감염 흐름은 세 파일을 중심으로 진행됨
    • build-to-host.m4: 다음 단계 스크립트를 추출하는 빌드 스크립트
    • bad-3-corrupt_lzma2.xz: 셸 스크립트가 숨겨진 테스트 파일
    • good-large_compressed.lzma: 악성 바이너리 오브젝트가 숨겨진 테스트 파일
  • 추출된 악성 바이너리 구성요소는 컴파일 과정에서 정상 라이브러리와 링크되어 Linux 저장소로 전달될 수 있었음
  • 주요 벤더는 이 악성 구성요소를 베타 및 실험 빌드에 포함해 배포함
  • XZ Utils 침해에는 CVE-2024-3094가 할당됐고, 심각도는 최대치인 10점

주요 타임라인

  • 2024년 1월 19일: 새 메인테이너 jiaT75가 XZ 웹사이트를 GitHub Pages로 이전함
  • 2024년 2월 15일: build-to-host.m4.gitignore에 추가됨
  • 2024년 2월 23일: 악성 스크립트 단계가 들어 있는 두 “테스트 파일”이 추가됨
  • 2024년 2월 24일: XZ 5.6.0이 릴리스됨
  • 2024년 2월 26일: CMakeLists.txt에 Landlock 보안 기능을 방해하는 커밋이 들어감
  • 2024년 3월 4일: 백도어가 Valgrind 관련 문제를 일으킴
  • 2024년 3월 9일: 두 테스트 파일이 갱신되고 CRC 함수가 수정됐으며 Valgrind 문제가 “수정”됨
  • 2024년 3월 9일: XZ 5.6.1이 릴리스됨
  • 2024년 3월 28일: 버그가 발견되고 Debian과 RedHat에 통보됨
  • 2024년 3월 28일: Debian이 XZ 5.6.1을 5.4.5-0.2 버전으로 롤백함
  • 2024년 3월 29일: OSS-security 메일링 리스트에 공개 메일이 게시됨
  • 2024년 3월 29일: RedHat이 Fedora Rawhide와 Fedora Linux 40 beta에 백도어 포함 XZ가 배포됐다고 확인함
  • 2024년 3월 30일: Debian이 빌드를 중단하고 재빌드 절차를 시작함
  • 2024년 4월 2일: XZ 메인 개발자가 백도어 사건을 인정함

감염 체인의 3단계

  • 1단계: 수정된 build-to-host.m4

    • XZ의 공식 GitHub 저장소 릴리스는 악성 테스트 파일을 포함했지만, 해당 파일들이 실행될 기회가 없어 처음에는 무해했음
    • 감염을 부트스트랩하는 악성 코드는 jiaT75가 제어하던 xz[.]tukaani.org에서 제공된 릴리스에 포함된 것으로 보임
    • 대부분의 배포판은 이 URL을 사용했고, 다운로드된 릴리스에는 악성 코드가 들어 있는 build-to-host.m4 파일이 포함됨
    • build-to-host.m4는 빌드 과정에서 실행되며 bad-3-corrupt_lzma2.xz의 “깨진” 데이터를 tr로 고친 뒤 xz -d로 압축 해제함
    • 압축 해제 결과에는 나중에 /bin/bash로 실행될 셸 스크립트가 들어 있음
  • 2단계: 삽입된 셸 스크립트

    • 악성 .m4 파일이 삽입한 스크립트는 Linux 머신에서 실행 중인지, 의도한 빌드 프로세스 안에서 실행 중인지 확인함
    • 다음 단계 실행에는 good-large_compressed.lzma가 사용됨
    • 이 파일은 XZ로 정상 압축되어 있지만, 압축 해제 데이터 안에 정크 데이터가 들어 있음
    • 스크립트는 head 파이프라인을 eval로 실행해 데이터를 추출함
    • head 명령은 다음 1024바이트를 무시하거나 다음 2048바이트 또는 724바이트를 추출함
    • 33,492바이트가 추출됨
    • tail은 파일의 마지막 31,265바이트를 유지하고 나머지를 무시함
    • 이후 tr로 기본 치환을 적용해 난독화를 풀고, 두 번째 XZ 명령이 변환된 바이트를 raw lzma 스트림으로 압축 해제한 뒤 결과를 셸로 전달함
  • 3단계: 백도어 오브젝트 추출

    • 마지막 단계 셸 스크립트는 예상 환경에서 실행 중인지 여러 조건을 확인함
    • 프로젝트가 IFUNC를 사용하도록 구성됐는지 확인함
    • GCC로 컴파일되는지 확인함
    • 이후 스크립트가 사용할 특정 파일이 프로젝트에 존재하는지 확인함
    • 이 단계는 good-large_compressed.lzma의 다른 오프셋에 숨겨진 오브젝트 파일을 추출함
    • 추출 절차는 여러 명령을 순차 실행하고, 각 명령의 출력을 다음 명령의 입력으로 넘김
    • XZ 도구로 good-large_compressed.lzma를 추출함
    • eval $i와 여러 head 호출을 사용함
    • RC4와 유사한 커스텀 알고리듬으로 바이너리 데이터를 복호화함
    • 복호화된 압축 파일을 다시 XZ로 추출함
    • 앞부분 일부 바이트를 제거한 뒤 결과를 liblzma_la-crc64-fast.o로 저장함
    • 마지막으로 스크립트는 liblzmacrc_x86_clmul.h 파일에서 is_arch_extension_supported 함수를 수정함
    • __get_cpuid 호출을 _get_cpuid로 바꿔 밑줄 하나를 제거함
    • 이 변경으로 백도어 오브젝트가 라이브러리에 링크될 수 있음

바이너리 백도어 로딩 방식

  • 원래 XZ 코드에는 CRC 계산용 특수 함수 lzma_crc32lzma_crc64가 있음
  • 두 함수는 ELF 심볼 테이블에서 GLIBC의 IFUNC 타입으로 저장됨
    • IFUNC는 동적 링커가 공유 라이브러리를 로드할 때 사용할 함수를 동적으로 선택하게 함
    • XZ는 최신 프로세서 기능인 CLMUL, SSSE3, SSE4.1을 확인한 뒤 최적화된 CRC 함수를 사용할지 결정하기 위해 이 기능을 사용함
  • 프로세서 기능 확인에는 cpuid 명령이 필요하고, GLIBC가 제공하는 __get_cpuid 래퍼가 호출됨
  • 악성 스크립트가 __get_cpuid_get_cpuid로 바꾸면서, 코드 호출은 백도어 오브젝트 파일 안의 _get_cpuid 심볼로 연결됨
  • 초기 백도어 코드는 lzma_crc32lzma_crc64가 같은 수정 함수 _get_cpuid를 사용하기 때문에 두 번 호출됨
    • 단순 카운터로 이미 실행됐는지 확인함
    • lzma_crc64 IFUNC가 _get_cpuid를 호출하고 카운터 값이 1이면 최종 진입점으로 리다이렉션하는 단계가 시작됨

런타임 동작과 후킹 대상

  • 백도어는 실행 중인 프로세스의 핵심 정보를 담는 구조체들을 초기화함
  • 하드코딩된 오프셋으로 Global Offset Table(GOT) 주소를 찾고, 그 안의 cpuid 포인터를 찾음
  • 이후 포인터를 메인 악성 함수로 바꿔 cpuid를 호출하는 것처럼 악성 함수를 호출함
  • 주 목표는 감염된 머신으로 들어오는 연결을 감시할 수 있도록 특정 함수를 후킹하는 것임
  • 표적 함수는 libcrypto와 관련됨
    • RSA_public_decrypt: 개인키로 서명된 암호문을 복호화할 때 사용됨
    • EVP_PKEY_set1_RSA: 특정 컨텍스트의 RSA 키를 설정할 때 사용됨
      • 최신 SSH 서버 버전에는 없지만 독립 SSH 키 생성 도구에서 사용됨
    • RSA_get0_key: RSA 키를 가져올 때 사용됨
  • 후킹 과정은 여러 내부 구조체 접근과 프로세스별 구조체 조작이 필요하며, 악성 코드는 분석 회피를 위한 검사를 함께 수행함

실행 환경 검사와 분석 회피 기법

  • sshd와 킬 스위치 확인

    • 백도어는 먼저 심볼 주소를 동적으로 해석하는 ld-linux 동적 링커를 파싱함
    • 현재 실행 환경이 기준에 맞는지 확인함
    • 현재 프로세스가 /usr/bin/sshd인지 확인함
    • 킬 스위치가 존재하는지 확인함
    • 현재 프로세스 이름은 argv[0]에서 추출함
    • 프로세스 환경변수를 모두 파싱해 내부 문자열 테이블에 있는 값과 일치하는지 확인함
    • 일치하는 환경변수가 있거나 프로세스가 sshd가 아니면 악성 코드는 실행을 중단함
    • 내부 테이블의 유일한 변수 yolAbejyiejuvnup=Evjtgvsh5okmkAvj는 이 맥락에서 킬 스위치로 동작함
  • trie 기반 문자열 처리

    • 백도어의 특징 중 하나는 문자열 작업에 단일 trie 구조를 사용한다는 점임
    • 함수 이름 같은 상수를 직접 비교하거나 문자열 해시로 비교하는 대신, trie 조회 결과가 특정 상수값과 같은지 확인함
    • ELF 헤더의 매직값은 trie에서 0x300을 반환함
    • system 함수 이름은 0x9F8 반환값과 매칭됨
    • trie는 비교뿐 아니라 호스트 바이너리 안의 문자열을 찾는 데도 사용됨
    • 예시로 ssh-2.0 같은 문자열 포인터를 사용하는 함수는 백도어 본문에 의심스러운 데이터가 남지 않도록 호스트 바이너리에서 문자열을 찾음
    • 구현은 16바이트 비트마스크를 사용함
    • 각 절반은 입력 바이트 범위 0x00-0x3F, 0x40-0x7F에 대응함
    • trie 리프 노드는 2바이트이며, 3비트는 플래그로 쓰이고 나머지는 값 또는 다음 노드 위치로 예약됨

심볼 해석과 rtdl-audit 후킹

  • 심볼 해석 루틴

    • 백도어에는 ELF Symbol 구조를 찾기 위한 심볼 해석 루틴이 최소 3개 있음
    • 모든 심볼 해석 함수는 trie에서 검색할 키를 입력으로 받음
    • 한 해석 함수는 모든 심볼을 순회하며 원하는 키를 가진 심볼을 찾고, 발견되면 Elf64_Sym 구조를 반환함
    • 이 구조는 이후 백도어 내부 구조체를 채워 필요한 함수 포인터들을 보관하는 데 사용됨
    • 이 과정은 Windows 위협에서 흔히 보이는 API 해싱 루틴과 유사함
    • 백도어는 이후 암호화 루틴에서 사용할 OpenSSL libcrypto 함수들을 다수 검색함
    • 찾고 해석한 함수 수를 추적하며, 이 값으로 정상 실행 여부와 중단 여부를 결정함
  • lzma_alloc를 악용한 가짜 allocator

    • 또 다른 심볼 해석기는 liblzma 자체 함수인 lzma_alloc를 악용함
    • lzma_alloc는 기본 allocator인 malloc 또는 커스텀 allocator를 사용해 메모리를 효율적으로 할당하도록 돕는 함수임
    • XZ 백도어에서는 가짜 allocator를 통해 이 함수가 또 다른 심볼 해석기처럼 동작함
    • 원래 “할당 크기”로 쓰이는 매개변수는 실제로 trie 내부의 심볼 키로 사용됨
    • 이 트릭은 백도어 분석을 어렵게 만들기 위한 목적임
    • 백도어는 실행 중 심볼을 동적으로 해석하며, 모든 심볼을 한 번에 해석하거나 필요한 순간에만 해석하는 방식으로 제한되지 않음
    • 해석 대상에는 정상 OpenSSL 함수부터 머신에서 명령을 실행하는 system 같은 함수까지 포함됨
  • rtdl-audit 런타임 패치

    • 백도어는 함수 후킹을 위해 동적 링커의 rtdl-audit 기능을 사용함
    • 일반적으로 rtdl-audit는 개발자가 커스텀 공유 라이브러리를 만들어 심볼 해석 같은 링커 이벤트를 통지받는 기능임
    • XZ 백도어는 별도 공유 라이브러리를 만드는 대신, 메모리에 이미 등록된 기본 인터페이스를 런타임 패치해 심볼 해석 루틴을 탈취함
    • 동적 링커 메모리 영역의 dl_audit 전역 변수에 저장된 악성 audit_iface 구조체에는 symbind64 콜백 주소가 들어 있음
    • 동적 링커가 이 콜백을 호출하면 모든 심볼 정보가 백도어 제어로 넘어가고, 표적 함수에 대해 악성 주소를 반환해 후킹이 달성됨
    • dl_auditdl_naudit 주소는 dl_maindl_audit_symbind_alt 함수를 디스어셈블해 얻음
    • 백도어에는 명령어 디코딩을 위한 내부의 최소형 디스어셈블러가 포함되어 있으며, *audit 주소 같은 특정 값을 찾을 때 폭넓게 사용됨

확인된 백도어 배포본과 탐지 정보

  • 백도어 포함 소스 배포본

    • xz-5.6.0
      • MD5: c518d573a716b2b2bc2413e6c9b5dbde
      • SHA1: e7bbec6f99b6b06c46420d4b6e5b6daa86948d3b
      • SHA256: 0f5c81f14171b74fcc9777d302304d964e63ffc2d7b634ef023a7249d9b5d875
    • xz-5.6.1
      • MD5: 5aeddab53ee2cbd694f901a080f84bf1
      • SHA1: 675fd58f48dba5eceaf8bfc259d0ea1aab7ad0a7
      • SHA256: 2398f4a8e53345325f44bdd9f0cc7401bd9025d736c6d43b372f4dea77bf75b8
  • 분석된 주요 아티팩트

    • bad-3-corrupt_lzma2.xz: 86fc2c94f8fa3938e3261d0b9eb4836be289f8ae
    • build-to-host.m4: b4dd2661a7c69e85f19216a6dbbb1664
    • good-large_compressed.lzma: 540c665dfcd4e5cfba5b72b4787fec4f
    • liblzma_la-crc64-fast.o: 212ffa0b24bb7d749532425a46764433
  • 알려진 백도어 포함 라이브러리

    • Debian Sid liblzma.so.5.6.0
      • MD5: 4f0cf1d2a2d44b75079b3ea5ed28fe54
      • SHA1: 72e8163734d586b6360b24167a3aff2a3c961efb
      • SHA256: 319feb5a9cddd81955d915b5632b4a5f8f9080281fb46e2f6d69d53f693c23ae
    • Debian Sid liblzma.so.5.6.1
      • MD5: 53d82bb511b71a5d4794cf2d8a2072c1
      • SHA1: 8a75968834fc11ba774d7bbdc566d272ff45476c
      • SHA256: 605861f833fc181c7cdcabd5577ddb8989bea332648a8f498b4eef89b8f85ad4
  • 탐지명

    • Kaspersky 제품은 공격 관련 악성 객체를 HEUR:Trojan.Script.XZTrojan.Shell.XZ로 탐지함
    • Kaspersky Endpoint Security for Linux는 Critical Areas Scan 작업의 일부로 SSHD 프로세스 메모리 안의 악성 코드를 MEM:Trojan.Linux.XZ로 탐지함
    • 제공된 Yara 규칙은 CVE-2024-3094와 관련된 악성 get_cpuid 함수를 찾기 위한 liblzma_get_cpuid_function 규칙임

댓글과 토론

Hacker News 의견들
  • 이 문장은 실제로 벌어진 일을 오히려 축소해서 말하는 것 같음
    백도어의 기술적 측면보다 더 무서운 건 사회공학의 양과 수준임. 백도어는 최종 산물이었고, 그걸 넣을 수 있었던 건 그 시점에 xz 프로젝트 전체가 이미 악의적 행위자들, 즉 “Jia Tan”과 그 주변에 장기간 장악돼 있었기 때문임. 유지보수자를 상대로 1년 넘게 심리전을 벌였고, 유지보수자나 다른 누구도 알아채지 못했음
    첩보소설 같은 일이고, 이런 일이 가능하다면 지금 다른 프로젝트들에서는 또 무슨 일이 벌어지고 있을지 궁금해짐
    백도어 코드 자체에도 같은 사고방식이 드러남. 단순히 무해해 보이려는 게 아니라 커밋 메시지, 주석, 변수명, 명령 선택 등을 통해 겉으로는 어떤 일을 하는지에 대한 서사를 적극적으로 만들고, 실제로는 완전히 다른 일을 하게 해 둠. 코드를 먼저 살펴본 사람이 자기 이해를 의심하고, 그다음 버그를 의심하다가, 한참 뒤에야 악의를 의심하게 만드는 구조임

    • 정말 믿기 어려운 수준임. 음모론처럼 들릴 수 있지만, 원저자가 시간을 못 쓰게 되고 결국 나쁜 행위자에게 소유권을 넘기도록 현실 세계의 심리작전이 있었던 건 아닌지도 궁금함
      어떤 정보기관들이든 이 사건을 더 깊게 조사하고 있길 바람
    • 이 일을 교훈으로 삼았으면 함. 실제로 많은 일이 벌어지고 있음. 전 세계 정부 지원 기관과 암시장 조직들 중에는 백도어 확보를 임무로 삼는 곳이 많고, 자금도 충분함. 그게 그들의 일임
      백도어 관련 HN 스레드마다 이런 가능성을 편집증이나 알루미늄 호일 모자 취급하며 부정하는 걸 보면 답답함. 일어나지 않는 일인 것처럼 취급하지만, 이번엔 잡힌 구체적 사례일 뿐이고 아직 잡히지 않은 건 셀 수 없이 많음
      이번 건 오픈소스 프로젝트라 발견이 그나마 쉬운 편이었는데도 운이 좋았음. 이제 폐쇄소스 제품들을 생각해 보면, 백도어를 넣는 건 한 조직에 침투하거나 압박하는 문제로 줄어듦. 이런 일은 자주 일어남. 아무도 믿고 싶어 하지 않지만 흔함. 기술 인프라 회사에서 일해 본 사람이라면 몇 가지 이야기가 있을 것임. NDA나 더 심한 이유로 말하기 어렵지만 실제로 벌어짐
    • 코드를 살펴보는 사람이 자기 이해를 의심하게 만든다는 점에 완전히 동의함. 이 일에 들어간 조작, 치밀함, 인내, 집요함이 놀라울 정도임
      누군가의 집착이 낳은 결과이거나, 이런 일을 여러 프로젝트에 대해 9시부터 5시까지 업무처럼 수행하는 민간 보안업체나 국가 행위자의 작업일 수 있음
  • 지금까지 관심이 백도어의 작동 성공과 목표 달성 방식에 집중된 건 당연함
    그래도 실수와 과도하게 설계된 부분에 대한 더 깊은 분석도 보고 싶음. Bryan Cantril 인터뷰 [1]에서 Andrés는 이게 배포 방식까지 꼭 알고 만든 게 아닌 기성 백도어 부품 같아서 어리석은 부분이 많다고 말함. 예를 들어 그가 조사하게 만든 심볼 테이블 조회가 그랬음
    마찬가지로 왜 RC4로 48바이트를 잘라냈는지도 궁금함 [2]
    시간이 더 있거나 더 나은 팀이었다면 어떻게 더 잘 만들 수 있었는지, 혹은 어디서 더 크게 실수했는지에 대한 이야기를 듣고 싶음
    [1] https://youtu.be/jg5F9UupL6I?si=gvXsYFXgagkGOMd4
    [2] https://twitter.com/matthew_d_green/status/17744729080201014...

  • 제대로 이해한 게 맞다면, 유용한 강화책은 각 동적 링크 라이브러리가 자기만의 GOT를 갖게 하고, 동적 링크가 끝나면 테이블을 읽기 전용으로 표시하는 것일 듯함. 즉 동적 경계를 넘어 다른 쪽의 ifunc 항목을 패치할 수 없게 하는 방식임
    이렇게 하면 어딘가에 링크되지만 실행되지는 않는 코드의 공급망 보안이 개선될 수 있음
    더 나아가 ifunc를 선언형 방식으로 구현해서, 링크하는 각 라이브러리에서 임의 코드 실행을 일으키지 못하게 하는 편이 더 나을 수도 있음. 하위 호환성 때문에 지금 구현은 어렵겠지만, 장기적으로는 계층적으로 도입할 수 있어 보임. 예를 들어 어떤 라이브러리를 “선언형 링크 ifunc” 기능 비트로 빌드하면, 동적 링커가 연결된 모든 라이브러리에 같은 기능 플래그가 없을 때 실행을 실패시키는 식임

    • 다른 각도에서는 빌드 시스템이 문제임
      현재 대부분의 라이브러리 빌드는 튜링 완전한 환경을 요구하는 매우 복잡하고 난해한 스크립트들을 실행하는 식임. 이건 공격자에게 끝없는 공격 표면을 주고, 빌드 과정이 탈취되면 기회가 생김
      실행기를 제한된 상태 기계로만 둔 선언형 빌드 과정으로 옮기면 도움이 될 것임. 모든 소스 덩어리가 재현 가능해야 한다는 요구도 생각해 볼 만함
    • 맞기도 하고 아니기도 한데, 대체로는 아님. 이런 방식은 ifunc를 이런 식으로 단순히 쓰는 건 막겠지만, 중요한 건 이 백도어 작성자가 민감한 프로세스의 주소 공간에 들어가는 라이브러리에 임의 코드를 주입할 수 있었다는 점임
      그 시점부터는 모든 방어가 무력해짐. 원하면 GOT를 쓰기 가능으로 다시 매핑할 수 있고, 그런 행동이 “수상함”으로 탐지되거나 운영체제가 전환을 막을 수 있어도, 주입된 코드는 수백 가지 다른 방식으로 제어 흐름을 뒤집을 수 있음. 임의 읽기/쓰기, 코드 실행, 모든 것이 가능함. 이 단계의 침해를 막을 보안 완화책은 없음. 원하면 개인키를 유출해서 공격자에게 직접 보낼 수도 있고, 셸을 띄울 수도 있음. 이 단계에서 보호 설계를 하려는 건 헛수고임
    • 테이블을 동적 링크 완료 후 읽기 전용으로 표시하는 건 안타깝게도 동작하지 않음. 동적 링크는 지연 방식이라 “완료”되는 순간이 없음
      올바른 함수 포인터는 처음 호출될 때 로드되어 스텁 대신 테이블에 삽입되고, 그 시점은 임의로 먼 미래일 수 있음. 실제로 gtk 앱 같은 대형 라이브러리 생태계에서는 링크된 함수 대부분이 아예 호출되지 않음
    • 호스트 아키텍처용으로 빌드한다면 손해 없이 ifunc를 완전히 끌 수 있음. Gentoo에서는 -march=native로 빌드하는 일이 흔하고, glibc의 USE 플래그에서 -multiarch를 설정하면 ifunc 비활성화가 간단함. 부정적 영향은 보지 못했음
    • 라이브러리 가져오기를 샌드박스할 수 있는 프로그래밍 언어가 있나?
  • 처음 3단계에 관해서는 이 글이 지난 2주 동안 알려진 내용에 비해 많이 더하진 않음. 흐름도가 있는 좋은 정리글 정도임
    하지만 바이너리를 그 정도로 자세히 분석한 부분은 새로워 보임
    거기에 나온 소스 코드는 어떻게 만들어진 걸까? 역어셈블러를 돌리고, 코드가 하는 일을 이해한 뒤, 모든 이름을 설명적인 이름으로 바꾼 건가? 2주 만에 해낸 것치고는 상당한 성과처럼 보임

    • 저자는 GReAT임
      Global Research & Analysis Team, Kaspersky Lab
      https://securelist.com/author/great/
      글 작성자가 Kaspersky Lab의 악성코드 분석팀인 듯하니, 바이너리 역공학을 꽤 잘할 가능성이 높음
    • 흰색 스크린샷에 쓰인 도구는 디컴파일러인 IDA Pro
      https://hex-rays.com/ida-pro/
  • 정말 궁금한 건 xz 조사를 촉발한 SSH 초기 지연이 정확히 무엇 때문에 생겼는지임. 누가 밝혀냈나?

    • 연결마다 추가 ECC 연산을 수행하지만, 최신 CPU에서 500ms가 걸릴 일은 아님
      코드를 역공학한 사람들에 따르면 명령 메시지를 SSH 호스트 키와도 묶어야 한다고 함. 그래서 호스트 키가 RSA 키라면 연결마다 추가 RSA 복호화 연산도 수행했을 수 있음
      그거라면 지연 원인으로 충분할 듯함
    • 일부러 그랬을 수 있음
      먼저 코드 주입을 시도하지 않고도, 바깥에서 서버가 감염됐는지 알아내는 쉬운 방법임
  • 작성자들은 glibc 내부 구조를 아주 깊게 알고 있음. 소스 코드에 목까지 파묻혀 있어야 알 수 있는 종류의 내용이고, 새로운 기법도 많음
    커스텀 ELF 파서와 디스어셈블러가 너무 복잡해서, 그 코드를 과거에 다른 곳에서 쓰지 않았거나 앞으로도 다시 쓰지 않을 거라고 상상하기 어려움
    이 사건이 마땅한 수준의 진지한 조사를 받을지 궁금하지만, 그럴 것 같지는 않음

  • 결국 이 일을 드러나게 한 Valgrind 오류와 SSH 느려짐을 일으킨 백도어 버그를 분석한 사람이 있나?

    • 명백히 잘못된 메모리 쓰기였던 듯함: https://www.mail-archive.com/valgrind-users@lists.sourceforg...
      Valgrind “수정”은 ifunc를 비활성화하는 것이었고, 그 결과 백도어가 비활성화되어 오류가 사라짐
      느려짐은 내가 알기로 백도어가 수행한 모든 심볼과 명령어 조회에서 비롯됨
  • 반전으로 보면, 공격자가 스크립트와 코드에서 탐지를 피하려고 들인 노력을 생각할 때 이 프로젝트 전체가 주의 분산용이거나, 동시에 여러 시도가 진행되는 동안의 예비책일 수도 있음
    이런 것보다 한발 앞서려면 어떻게 해야 할까? 커뮤니티가 SSHD에 집중하는 것이 시스템 전체의 다른 부분에 영향을 줄까? 다른 기술적 측면이나 사회적 측면에는?
    알루미늄 호일 모자는 재미있음

    • 낙관적이지 않음. Flathub의 flatpak 바이너리 내용을 실제로 감사하는 사람도 거의 없음. 정말 소스에서 빌드됐는지? 작성자가 그렇다고 증명한다는 식임. 이런 백도어처럼 정교한 전달 메커니즘조차 필요 없을 수 있음
    • 모든 것을 직접 작성하고, 검증된 개발자들로 구성된 전담 팀을 둘 수 있음
      아니면 Microsoft 같은 곳의 폐쇄소스를 사서, 그들이 코드를 더 엄격하게 검토할 자원과 의지가 있기를 바라는 방법도 있음
      그리고 이상한 네트워크 활동과 권한 상승 시도를 탐지할 훌륭한 보안 운영팀을 두는 접근도 항상 있음
    • 비슷한 백도어보다 한발 앞서는 방법으로는 sshd 트래픽을 spiped 터널로 감싸는 걸 생각함. Spiped는 소스에서 컴파일하고 정적 링크하며, 마지막 안정 버전은 2021년 것임
    • 오픈소스 기여자를 의심하자는 게 내 알루미늄 호일 모자 아이디어임. 특정 국가 출신이라서도 아니고, 실제로 만난 적 없어 보여서도 아님
      다만 작업 중인 프로젝트 외에는 이력도 발자국도 없는 기여자는 앞으로 위험 신호로 봐야 함
    • 알루미늄 호일 모자는 필요 없음. FOSS 프로젝트는 유명해지기 전부터 백도어가 심어져 왔고, 이번 차이는 국가 지원 행위자가 한다는 점임
      예전 그룹인 GOBBLES, ADM, ac1db1tch3z, ~el8도 이런 일을 했고, isec.pl 같은 민간 “보안 연구자”들도 했음
      이번이 문제가 되는 건 국가 행위자들이 기반 프로젝트를 저임금으로 떠받치는 시대를 만든 기업 자본주의를 악용하고 있기 때문임. 악성 행위자들은 목표 달성을 위한 자원이 사실상 무제한임
      그게 결국 NSO, Zerodium 같은 조직의 수요와 탄생을 만든 셈임
      그 이전에는 익스플로잇과 백도어의 가치가 거의 없었고, 해커들은 Qualys 같은 회사의 후원이나 채용을 기대했음
  • Google의 제로데이 취약점 해킹 분석을 몇 번 봤는데 그것들도 비현실적으로 대단했지만, 이번 해킹은 역대급 중 하나일 것 같음

  • xz 저장소가 GitHub에 다시 올라온 걸 봤고, Lasse와 새 기여자가 정리 중이었음. ifunc 지원을 제거했고, blob 없이 테스트 파일을 만들 수 있도록 테스트 파일 생성 코드를 저장소에 커밋했음. 좋은 방향으로 작업하는 것처럼 보임