- ์ฒด์ธ๋ช : XZ Utils(liblzma) ๋ฐฑ๋์ด โ ์คํ์์ค ๊ณต๊ธ๋ง ์นจํฌ โ ๋น๋ ์์ ์ฝ๋ ์ฃผ์ โ OpenSSH ์ธ์ฆ ์ฐํ
- ํต์ฌ ์ทจ์ฝ์ : CVE-2024-3094 (CVSS 3.1 10.0 โ AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)
- ์ํฅ ๋ฒ์ : xz/liblzma 5.6.0(2024-02-24) ยท 5.6.1(2024-03-09) ยท ์์ : 5.6.2(2024-05-29)
- ๋ฐ๊ฒฌ: Andres Freund (Microsoft, PostgreSQL ๊ฐ๋ฐ์) โ Debian ๊ฐ๋ฐํ์์ SSH ์ง์ฐยทCPU ๊ธ์ฆ์ ์ถ์ ํ๋ค ๋ฐ๊ฒฌ, 2024-03-29 ๊ณต๊ฐ(Openwall oss-security)
- ๊ณต๊ฒฉ์: 2๋ ๊ฐ ์ ๋ขฐ๋ฅผ ์์ ๊ณต๋ ๊ด๋ฆฌ์๊ฐ ๋ ์์ฅ ์ธ๋ฌผ "Jia Tan"(JiaT75) โ APT29(SVR) ์ฐ๊ณ ์ถ์ , ๊ณต์ ๊ท์์ ์์
- ๋ฐ๋ ์กฐ๊ฑด: x86-64 Linux + glibc + GCC + tarball๋ก ๋น๋ + sshd๊ฐ systemd(libsystemd)๋ฅผ ํตํด liblzma๋ฅผ ๋ก๋ํ๋ ๊ฒฝ์ฐ์๋ง ํ์ฑ
- ์ค์ ํผํด: ๋กค๋ง/๊ฐ๋ฐํ ๋ฐฐํฌํ์ ๊ตญํ(Fedora Rawhideยท41, Debian sid, openSUSE Tumbleweed ๋ฑ) โ ๋์ ์คํผํด๋ ๋ฏธ๋ฐ์, 'ํ๋งํฐ๋ฉด'์ ์ฌ๊ฑด
1. ๋ฐฐ๊ฒฝ/์ญ์ฌ โ ๋๊ตฌ๋ ์ฐ์ง๋ง ์๋ฌด๋ ์ ๋ณด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
XZ Utils๋ ๋ฆฌ๋ ์ค์์ ํ์ผ์ ์์ถํ๋ ์์ฃผ ํํ ๋๊ตฌ์ด์, ๊ทธ ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ liblzma๋ฅผ ์ ๊ณตํ๋ ํ๋ก์ ํธ๋ค. ๊ฑฐ์ ๋ชจ๋ ๋ฆฌ๋ ์ค ๋ฐฐํฌํ์ ๊น๋ ค ์์ง๋ง, ์ผ๋ฐ ์ฌ์ฉ์๋ ๋ฌผ๋ก ๋๋ถ๋ถ์ ๊ฐ๋ฐ์๋ ๊ทธ ์กด์ฌ๋ฅผ ์์ํ์ง ์๊ณ ์ง๋์น๋ค. ์ด๋ฐ '๋ณด์ด์ง ์๋ ์์กด์ฑ'์ด ๋ฐ๋ก ๊ณต๊ธ๋ง ๊ณต๊ฒฉ์ ์ต์ ํ์ ์ด๋ค.
ํ๋ก์ ํธ๋ ์ค๋ ๊ธฐ๊ฐ Lasse Collin์ด ์ฌ์ค์ ํผ์ ์ ์ง๋ณด์ํ๊ณ ์์๋ค. 2021๋ ๋ถํฐ "Jia Tan"์ด๋ผ๋ ์ด๋ฆ์ ๊ธฐ์ฌ์๊ฐ ๋ฑ์ฅํด ๊พธ์คํ ํจ์น๋ฅผ ์ ์ถํ๋ฉฐ ์ ๋ขฐ๋ฅผ ์์๊ณ , ์ฌ๋ฌ ๊ฐ์ ๊ฐ์ง (sock-puppet) ๊ณ์ ์ผ๋ก "๊ด๋ฆฌ์๋ฅผ ๋ ๋์"๋ ์๋ฐ ์ฌ๋ก ์ ๋ง๋ค์๋ค. ๊ฒฐ๊ตญ ๊ทธ๋ ํ๋ก์ ํธ์ ๊ณต๋ ๊ด๋ฆฌ์ ๊ถํ์ ์ป์๊ณ , ๊ทธ ๊ถํ์ผ๋ก 2024๋ 2์ 5.6.0 / 3์ 5.6.1 ๋ฆด๋ฆฌ์ค์ ๋ฐฑ๋์ด๋ฅผ ์ฌ์๋ค.
- ์ ์ ๋ช ํ๊ฐ: ์ ์ฑ์ฝ๋๊ฐ ๋ฐ์ด๋๋ฆฌ๋ก ๋ฐฐํฌ๋ ๊ฒ์ด ์๋๋ผ '์์ค ์ ์ฅ์์ ๋น๋ ์ ์ฐจ'์ ์จ์ด ๋ค์ด๊ฐ๋ค. ์ฌ์ฉ์๊ฐ ๋ฐ๋ ์์ถ tarball ์์์๋ง ๋์ํ๋๋ก ์ค๊ณ๋ผ, ๋์ผ๋ก ์ฝ๋๋ฅผ ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ํต์งธ๋ก ์ฐํํ๋ค. '์ฐ๋ฆฌ๊ฐ ์ฝ๋ ์ฝ๋'์ '์ค์ ๋ก ์ปดํ์ผ๋๋ ์ฝ๋'๊ฐ ๋ค๋ฅผ ์ ์๋ค๋ ์ฌ์ค์ ์ธ์์ ๊ฐ์ธ์ํจ ์ฌ๊ฑด์ด๋ค.
- 2๋ ์ง๋ฆฌ ์ฅ๊ธฐ์ : ๋จ์ ์ต์คํ๋ก์์ด ์๋๋ผ ์ธ๊ฐ ๊ด๊ณ๋ฅผ ๊ณต๋ตํ๋ ์ฌํ๊ณตํ ์บ ํ์ธ์ด์๋ค. ์ด๋ ์คํ์์ค ์ ์ง๋ณด์์์ ๋ฒ์์๊ณผ '๊ด๋ฆฌ์ ๋ถ์กฑ'์ด๋ผ๋ ๊ตฌ์กฐ์ ์ฝ์ ์ ์ ๋ฉด์ผ๋ก ๊ฒจ๋ฅํ ์ต์ด์ ๋๊ท๋ชจ ์ฌ๋ก ์ค ํ๋๋ค.
- ์์ด๋ฌ๋ํ ๋ฐ๊ฒฌ: 2024-03-29, Microsoft์์ ์ผํ๋ PostgreSQL ๊ฐ๋ฐ์ Andres Freund๊ฐ Debian ๊ฐ๋ฐํ์์ 'SSH ์ ์์ด ์ด์ํ๊ฒ ๋๋ฆฌ๊ณ CPU๋ฅผ ์ก์๋จน๋๋ค, Valgrind๊ฐ ์๋ฌ๋ฅผ ๋ฑ๋๋ค'๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ถ์ ํ๋ค ๋ฐฑ๋์ด๋ฅผ ์ฐพ์๋๋ค. ๋ณด์ ์ค์บ๋๊ฐ ์๋๋ผ ๋๋ฆฐ SSH ํ๋๊ฐ ์ธ๊ณ๋ฅผ ๊ตฌํ ์ ์ด๋ค.
- ์ ๊ณ ํ์ฅ: GitHub๋ ํ๋ก์ ํธ ์ ์ฅ์๋ฅผ ์ผ์ ๋นํ์ฑํํ๊ณ , Red HatยทSUSEยทDebian ๋ฑ์ ์ฆ์ ์ด์ ๋ฒ์ ์ผ๋ก ๋กค๋ฐฑํ๋ค. Canonical์ Ubuntu 24.04 LTS ๋ฒ ํ๋ฅผ 1์ฃผ์ผ ๋ฆ์ถ๊ณ ์ ์ฒด ํจํค์ง๋ฅผ ๋ฐ์ด๋๋ฆฌ ์ฌ๋น๋ํ๋ค.
2. ๊ฐ์ผยท์ ํ ๊ฒฝ๋ก โ '์ฌ๋'์ ๋ซ๊ณ '๋น๋ ์๋ฒ'๋ก ๋ค์ด๊ฐ๋ค
์ด ์ฌ๊ฑด์ '์ ํ ๊ฒฝ๋ก'๋ ๋คํธ์ํฌ๊ฐ ์๋๋ผ ์ ๋ขฐ์ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ด๋ค. ์ ์ฑ์ฝ๋๋ ์ฌ์ฉ์ PC๋ก ์ง์ ๋ฐฐํฌ๋์ง ์๊ณ , ๋ฐฐํฌํ์ด ์์ค๋ฅผ ๋น๋ํ๋ ์๊ฐ ์ด์๋๋ค.
- โ ์ ๋ขฐ ์ถ์ (2021~2023): Jia Tan์ด ์ ์ ํจ์น๋ฅผ ๊ณ์ ์ ์ถํ๊ณ , ๊ฐ์ง ๊ณ์ ๋ค๋ก "์ ๊ด๋ฆฌ์๊ฐ ํ์ํ๋ค"๋ ์ฌ๋ก ์ ์กฐ์ฑํด ๊ณต๋ ๊ด๋ฆฌ์ ์๋ฆฌ๋ฅผ ์ป๋๋ค. ์ ์ฑ์ฝ๋๊ฐ ์๋๋ผ ์ ๋ขฐ๋ฅผ ๋จผ์ ์ฌ๋๋ค.
- โก ์๋ ์ฃผ์
(2024-02~03): 5.6.0/5.6.1์ tarball์๋ง
build-to-host.m4์ ๋ณ์กฐ ๋ฒ์ ์ ๋ฃ๋๋ค. git ์ ์ฅ์์๋ ์ ์ ์คํฌ๋ฆฝํธ๊ฐ ์์ด ๋ฆฌ๋ทฐ์์ ์๋ฌด ๋ฌธ์ ๊ฐ ์ ๋ณด์ธ๋ค. - โข ๋น๋ ์์ ์คํ: ๋ฐฐํฌํ์ด tarball์ ๋ฐ์ ๋น๋ํ ๋, ๋ณ์กฐ๋ m4 ์คํฌ๋ฆฝํธ๊ฐ
tests/files/์์ '์ ์ ํ ์คํธ ๋ฐ์ดํฐ'๋ก ์์ฅํ ํ์ผ์ ๋์ฝ๋ํด ์ ์ฑ ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ค์ด ์ ์ ์ค๋ธ์ ํธ๋ฅผ ๋ฎ์ด์ด๋ค. - โฃ ๋ฐฐํฌํ ํจํค์ง: ๊ฒฐ๊ณผ๋ฌผ์ ์๋ช ๋ ์ ์ ํจํค์ง๋ก ๋น๋๋ผ ๋ฐฐํฌ๋๋ค. ๋น๋ ์ดํ ๋จ๊ณ์ ์ด๋ค ์๋ช ยทํด์ ๊ฒ์ฆ๋ ์ด ๋จ๊ณ์์์ ๋ณ์กฐ๋ ์ก์ง ๋ชปํ๋ค.
- โค sshd์์ ๋ฐ๋: ํผํด ์์คํ ์ sshd ํ๋ก์ธ์ค๊ฐ liblzma๋ฅผ ๋ก๋ํ๋ ์๊ฐ(systemd ๊ฒฝ์ ), ๋ฐฑ๋์ด๊ฐ ์ด๋ฆฐ๋ค. ์ดํ ํน์ Ed448 ๊ฐ์ธํค๋ฅผ ๊ฐ์ง ๊ณต๊ฒฉ์๊ฐ ๋น๋ฐ๋ฒํธยท์ธ์ฆ ์์ด ์๊ฒฉ์์ ๊ด๋ฆฌ์ ๊ถํ์ ์ป์ ์ ์์๋ค.
์ฆ ์ ํ์ ํต์ฌ์ 'ํ ์คํธ ๋ฐ์ดํฐ๋ก ์์ฅ โ ๋น๋ ์ ์คํ โ ์ ์ ํจํค์ง๋ก ์์ฅ'์ด๋ผ๋ 3์ค ์์ฅ์ด๋ค. ๊ทธ๋์ ์ทจ์ฝํ ๋ฒ์ ์ด ๋ฐฐํฌํ์ ๋ค์ด๊ฐ๊ธฐ ์ ๊น์ง ๋๊ตฌ๋ ๋์น์ฑ์ง ๋ชปํ๋ค.
3. ๋์ ์๋ฆฌ ์์ธ ๋ถ์ โ ์ ์์ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ SSH๋ฅผ ๊ฑด๋๋ฆฌ๋
๊ฐ์ฅ ๋ง์ด ๋์ค๋ ์ง๋ฌธ์ด "์์ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด๋ป๊ฒ SSH ์ธ์ฆ์ ์ฐํํ๋?"๋ค. ๋ต์ liblzma๊ฐ sshd ํ๋ก์ธ์ค ์์ '๊ฐ์ด ๋ก๋๋๋ค'๋ ์ ์ ์๋ค.
- ์ฐ๊ฒฐ ๊ณ ๋ฆฌ(systemd): ์ฌ๋ฌ ๋ฐฐํฌํ์ OpenSSH๋ฅผ ํจ์นํด systemd
์๋ฆผ์ ์ฐ๊ฒ ํ๋ค. sshd โ
libsystemdโliblzma์์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํจ๊ป ๋ก๋๋๋ค. ์ฆ liblzma์ ์ฝ๋๊ฐ sshd์ ์ฃผ์ ๊ณต๊ฐ ์์์ ์คํ๋๋ค. - IFUNC ๋ฆฌ์กธ๋ฒ ์ ์ฉ: liblzma์ CRC64 ํจ์๋ IFUNC(Indirect Function)๋ก ๊ตฌํ๋ผ ์๋ค. IFUNC๋ ๋ก๋๊ฐ ํ๋ก๊ทธ๋จ์ ์์ํ ๋ '์ค์ ํจ์ ์ฃผ์๋ฅผ ๊ณ์ฐํ๋ ๋ฆฌ์กธ๋ฒ'๋ฅผ ์คํํ๋ค. ๋ฐฑ๋์ด๋ ๋ฐ๋ก ๊ทธ ๋ฆฌ์กธ๋ฒ์ ์ฝ๋๋ฅผ ์ฌ์ด, main()์ด ์คํ๋๊ธฐ๋ ์ ์ ๊ณต๊ฒฉ์ ์ฝ๋๊ฐ ๋๊ฒ ๋ง๋ค์๋ค.
- OpenSSL ํํน: ํ๋ก์ธ์ค์ ์ง์
ํ ๋ฐฑ๋์ด๋ OpenSSL์
RSA_public_decrypt()๋ฑ ์ธ์ฆ ๊ด๋ จ ํจ์๋ฅผ ๊ฐ๋ก์ฑ๋ค. ์ ์ ์ธ์ฆ ํ๋ฆ ์ฌ์ด์ ๋ผ์ด๋ค์ด, ๊ณต๊ฒฉ์๊ฐ ์ค๋นํ ํน์ Ed448 ํค๋ก ์๋ช ๋ ๊ฐ์ ํ์ธํ๋ฉด ์ธ์ฆ์ ํต๊ณผ์์ผ ๋ฒ๋ฆฐ๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋น๋ฐ๋ฒํธ ์์ด ๊ด๋ฆฌ์ ์ ๊ทผ์ด ๊ฐ๋ฅํด์ง๋ค. - ๋น๋ ์์ ํธ๋ฆฌ๊ฑฐ: ์ฃผ์ ์คํฌ๋ฆฝํธ๋ x86-64 Linux + glibc + GCC๋ก tarball์ ๋น๋ํ ๋๋ง ๋์ํ๋๋ก ์กฐ๊ฑด์ ๊ฑธ์๋ค. DebianยทRPM ํจํค์ง ํ๊ฒฝ์ ์ ํํ ๊ฒจ๋ฅํ '์ ๋ณ์ ' ์ค๊ณ์๋ค.
- ๋ค๋จ๊ณ ๋๋ ํ: ๋ฌด์์ ๋์ฝ๋ํ๋ฉด ๊นจ์ง๋๋ก, m4 ๋งคํฌ๋ก โ ์์ถ ํ์ผ โ ๋ ๋จ๊ณ ์ ธ ์คํฌ๋ฆฝํธ โ ์ต์ข ์ค๋ธ์ ํธ๋ก ์ด์ด์ง๋ ์ฌ๋ฌ ๊ฒน์ ์์ฅ์ ์์ ์ ์ ๊ฒ์ฌ๋ฅผ ํํผํ๋ค.
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ์ฃผ์ ๊ฒฝ๋ก | ๋ฆด๋ฆฌ์ค tarball์ build-to-host.m4 (git ์ ์ฅ์์๋ ์์) |
| ์์ฅ ์๋จ | tests/files/์ '์ ์ ํ
์คํธ ๋ฐ์ดํฐ'๋ก ์์ฅํ ์์ถ ํ์ผ |
| ์คํ ์์ | ํจํค์ง ๋น๋ ์(์ค๋ธ์ ํธ ๊ต์ฒด) + sshd ์์ ์(IFUNC ๋ฆฌ์กธ๋ฒ) |
| ํํน ๋์ | OpenSSL RSA_public_decrypt ๋ฑ ์ธ์ฆ ํจ์ |
| ์ธ์ฆ ์ฐํ ํค | ๊ณต๊ฒฉ์๊ฐ ๋ณด์ ํ ํน์ Ed448 ๊ฐ์ธํค |
| ๋ฐ๋ ์กฐ๊ฑด | x86-64ยทglibcยทGCCยทtarball ๋น๋ + sshd์ liblzma ๋ก๋ |
4. ํผํด ๊ท๋ชจ/์ํฅ โ '๋์ฌ์'์ด ๋ ๋ปํ ์ฌ๊ฑด
- ์ํฅ ๋ฒ์๋ ํ์ ์ : ๋ฐฑ๋์ด๋ 5.6.0ยท5.6.1 ๋ ๋ฒ์ ์๋ง ์์๊ณ , ์์ ํ ๋ฐฐํฌํ์ ๋๊ฐ 5.4.x๋๋ฅผ ์ฐ๊ณ ์์ด ์ทจ์ฝํ์ง ์์๋ค. Debian bookworm(5.4.1), Ubuntu ์์ ํ, macOS/Homebrew(sshd๊ฐ liblzma๋ฅผ ๋ก๋ํ์ง ์์) ๋ฑ์ ์ํฅ ์์.
- ์ทจ์ฝํ๋ ๊ณณ: Fedora RawhideยทFedora 41, Debian sid(๊ฐ๋ฐํ), openSUSE Tumbleweed, Kali ๋ฑ ๋กค๋ง/๊ฐ๋ฐํ์ด ์ฃผ ํ์ ์ด์๋ค. ์ด๋ค์ ๊ณต๊ฒฉ์ ์ ์ฅ์์ '๋ค์ ์์ ํ์ ๋ค์ด๊ฐ๊ธฐ ์ ๋ฏธ๋ฆฌ ์ฌ์ด๋๋ ๋ฐํ'์ด์๋ค.
- ์ ์คํผํด๊ฐ ์์๋: 5.6.0 ๊ณต๊ฐ(2์)๋ถํฐ ๋ฐ๊ฒฌ(3์ ๋ง)๊น์ง ์ฝ ํ ๋ฌ. ๋ง์ฝ ๋ฐ๊ฒฌ์ด ๋ช ๋ฌ๋ง ๋ฆ์๊ณ ๋ฐฑ๋์ด๊ฐ ๋ค์ ์์ ํ์๊น์ง ๋ค์ด๊ฐ๋ค๋ฉด, ์ ์ธ๊ณ ์๋ฐฑ๋ง ๋์ ์๋ฒ๊ฐ ๋์ผํ ํค ํ๋๋ก ๋ซ๋ฆด ์ ์์๋ค โ '์ญ์ฌ์ ์ต์ ์ ๊ณต๊ธ๋ง ์ฌ๊ณ '๊ฐ ๋ ๋ปํ๋ค.
- ๊ฒฝ์ ยท์ด์ ๋น์ฉ: ๊ฐ ๋ฐฐํฌํ์ด ๊ธด๊ธ ๋กค๋ฐฑยท์ฌ๋น๋ยท์ฌ๋ฐฐํฌ๋ฅผ ์ํํ๊ณ , Canonical์ Ubuntu 24.04 LTS ๋ฒ ํ๋ฅผ 1์ฃผ ์ฐ๊ธฐํ๊ณ ์ ์ฒด ํจํค์ง๋ฅผ ์ฌ๋น๋ํ๋ค. ์๋ง์ ๊ธฐ์ ์ด '๋ด ์์คํ ์ด 5.6.x๋ฅผ ์ฐ๋๊ฐ'๋ฅผ ํ์ธํ๋๋ผ ๊ธด๊ธ ์ ๊ฒ์ ๋ค์ด๊ฐ๋ค.
- ์ฃผ์ ํ๋ก์ ํธ ํ๊ธ: ๊ฐ์ ๊ณต๊ฒฉ์๊ฐ xz ์ธ์๋ libarchive, kmod, ๋ฆฌ๋ ์ค ์ปค๋ ๋ฑ ๋ค๋ฅธ ์คํ์์ค ํ๋ก์ ํธ์ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ์ ๊ทผํ ์ ํฉ์ด ๋ณด๊ณ ๋๋ค. ๋จ์ผ ํ๋ก์ ํธ๊ฐ ์๋๋ผ '์คํ์์ค ์ํ๊ณ ์ ์ฒด'๋ฅผ ๋ ธ๋ฆฐ ์บ ํ์ธ์ด์๋ค.
- ๊ท์: ๋ฏธ๊ตญ ๋ณด์ ์ฐ๊ตฌ์ Dave Aitel ๋ฑ์ APT29(๋ฌ์์ SVR ์ฐ๊ณ) ํจํด๊ณผ ์ ์ฌํ๋ค๊ณ ์ง์ ํ์ผ๋, ๊ณต์ ๊ท์์ ์์ง ์๋ค. ๊ตญ๊ฐ ๋ฐฐํ ๋๋ ๊ทธ์ ์คํ๋ ์์์ ๊ฐ์ง ํ์์๋ก ๋๋ฆฌ ์ถ์ ๋๋ค.
5. PoC (๊ฐ๋ ์ฆ๋ช ) โ ๊ต์ก์ฉ ๋ชจ์ ์ฌํ 4์ข
์๋ ์ฝ๋๋ ์ค์ ์ ์ฑ์ฝ๋๊ฐ ์๋๋ฉฐ, ์์์ ์ค๋ช ํ ๋ฉ์ปค๋์ฆ์ ์์ ํ ๋ชจ์ ๊ฐ์ฒด๋ก ์ฌํํ ๊ฒ์ ๋๋ค. ์ค์ ๋ฐฑ๋์ด ํ์ด๋ก๋ยท์ค์ ํํน ์ฝ๋ยท์ค์ ์ฐํ ํค๋ ํฌํจํ์ง ์์ต๋๋ค. ๊ฒฉ๋ฆฌ๋ ๋ฉ ํ๊ฒฝ(์ธํฐ๋ท ์ฐจ๋จ VM)์์๋ง ์คํํ์ธ์.
PoC โ ๋น๋ ์์ ์ฃผ์ โ 'ํ ์คํธ ๋ฐ์ดํฐ'๊ฐ ์ค๋ธ์ ํธ๋ก ๋ฐ๋๋ ์๊ฐ
import base64, zlib
# ์ ์ฅ์์๋ '๋ฌดํดํ ํ
์คํธ ๋ฐ์ดํฐ'์ฒ๋ผ ๋ณด์ด๋๋ก ์์ถ+base64๋ก ์์ฅํด ์ปค๋ฐํ๋ค.
_MOCK_PAYLOAD = b"[MOCK] replace crc64_fast.o with attacker object" # ๊ต์ก์ฉ ๋ชจ์ ๋ฌธ์์ด
CAMOUFLAGED = base64.b64encode(zlib.compress(_MOCK_PAYLOAD))
print("์ ์ฅ์์ ์ปค๋ฐ๋ 'ํ
์คํธ ํ์ผ':", CAMOUFLAGED[:48].decode(), "...")
# ๋น๋ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋๋ ์๊ฐ(=autoreconf / make) ํ์ด๋ก๋๊ฐ ๊บผ๋ด์ง๋ค.
def build_time_extract(blob):
return zlib.decompress(base64.b64decode(blob))
injected = build_time_extract(CAMOUFLAGED)
print("๋น๋ ์์ ์ ๊บผ๋ด์ง ๋ด์ฉ:", injected.decode())
# ์ ์ ๋น๋ ์ฐ์ถ๋ฌผ(clean .o)์ ์ด ๋ด์ฉ์ผ๋ก '๊ต์ฒด'ํ๋ค (๋ชจ์)
def compile_step(real_obj, injected):
return injected
print("๋น๋ ์ฐ์ถ๋ฌผ:", compile_step(b"crc64_fast.o (clean)", injected).decode())
์คํ ๊ฒฐ๊ณผ(์ด๋ฒ ์คํ ์ค์ ์ถ๋ ฅ):
์ ์ฅ์์ ์ปค๋ฐ๋ 'ํ
์คํธ ํ์ผ': eJyL9vV39o5VKEotyElMTlVILko2M4lPSywu0ctXKM8syVBI ...
๋น๋ ์์ ์ ๊บผ๋ด์ง ๋ด์ฉ: [MOCK] replace crc64_fast.o with attacker object
๋น๋ ์ฐ์ถ๋ฌผ: [MOCK] replace crc64_fast.o with attacker object
PoC โก IFUNC ๋ฆฌ์กธ๋ฒ โ 'main ์คํ ์ '์ ์ฝ๋๊ฐ ๋๋ ๊ตฌ์กฐ
/* hook_demo.c : IFUNC๋ก ์ฌ๋ณผ์ ๊ฐ๋ก์ฑ๋ '๊ธฐ๋ฒ'๋ง ์ฌํ (์ค์ ์ํธ ํจ์๋ ๊ฑด๋๋ฆฌ์ง ์์)
* build: gcc -O0 -o hook_demo hook_demo.c && ./hook_demo */
#define _GNU_SOURCE
#include <stdio.h>
static int real_check(int x) { return x * 2; } /* ์ ์ ๊ตฌํ */
/* ์ฌ๋ณผ์ด '์ฒ์ ์ฐธ์กฐ๋๋ ์๊ฐ' ๋ก๋๊ฐ ํธ์ถํ๋ ๋ฆฌ์กธ๋ฒ = ๋ฐฑ๋์ด ์ง์
์ (๋ชจ์) */
static int (*resolve_check(void))(int) {
fprintf(stderr, "[hook] ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋ ์์ ์ ๋ฆฌ์กธ๋ฒ ์คํ -> ๊ณต๊ฒฉ์ ์ฝ๋ ์ง์
(๋ชจ์)\n");
return real_check;
}
/* check()๋ฅผ IFUNC๋ก ์ ์ธ: ๋ก๋๊ฐ ์์๋ ๋ resolve_check()๋ฅผ ํธ์ถํด ์ค์ ํจ์ ์ฃผ์๋ฅผ ์ป๋๋ค */
int check(int) __attribute__((ifunc("resolve_check")));
int main(void) {
printf("check(21) = %d\n", check(21));
return 0;
}
์คํ ๊ฒฐ๊ณผ(์ด๋ฒ ์คํ ์ค์ ์ถ๋ ฅ): โ main()์ด ์ถ๋ ฅํ๋ ๊ฐ๋ณด๋ค
'๋ก๋ ์์ ' ๋ฉ์์ง๊ฐ ๋จผ์ ๋์ค๋ ๊ฒ์ ์ฃผ๋ชฉ.
[hook] ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋ ์์ ์ ๋ฆฌ์กธ๋ฒ ์คํ -> ๊ณต๊ฒฉ์ ์ฝ๋ ์ง์
(๋ชจ์)
check(21) = 42
PoC โข '์ ์ด๋ค ์์คํ ๋ง ์ํฅ๋ฐ๋' โ sshd์ liblzma ์ฐ๊ฒฐ ์ ๊ฒ
# xz ๋ฐฑ๋์ด๋ liblzma๊ฐ sshd ํ๋ก์ธ์ค์ '๋ก๋๋ ๋๋ง' ๋์ํ๋ค.
# systemd ๋ฐฐํฌํ์ sshd -> libsystemd -> liblzma ์์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋์ด์จ๋ค.
# ์๋๋ '๋ด sshd์ liblzma๊ฐ ๋ก๋๋๋๊ฐ'๋ฅผ ํ์ธํ๋ ์ฝ๊ธฐ ์ ์ฉ ์ ๊ฒ (๊ฒฉ๋ฆฌ ๋ฉ ์ ์ ).
echo "== liblzma/xz ํจํค์ง =="
(pacman -Q xz 2>/dev/null || dpkg -l 'liblzma*' 2>/dev/null | awk '/^ii/{print $2,$3}')
echo "== sshd์ liblzma ์ฐ๊ฒฐ =="
ldd "$(command -v sshd 2>/dev/null)" 2>/dev/null | grep -i lzma || echo "liblzma ๋ฏธ์ฐ๊ฒฐ (์ํฅ ์์)"
์คํ ๊ฒฐ๊ณผ(์ด๋ฒ ์คํ ์ค์ ์ถ๋ ฅ โ Arch Linux ๋ฉ VM):
== liblzma/xz ํจํค์ง ==
xz 5.8.3-1
== sshd์ liblzma ์ฐ๊ฒฐ ==
liblzma ๋ฏธ์ฐ๊ฒฐ (์ํฅ ์์)
์ด ๋ฉ ํ๊ฒฝ์ xz๋ ์ด๋ฏธ ํจ์น๋ 5.8.3์ด๊ณ , sshd์ liblzma๊ฐ ์ฐ๊ฒฐ๋์ง ์์ ๋ ์กฐ๊ฑด ๋ชจ๋ ์์ ํ๋ค. ์ค์ ์ฌ๊ฑด์์๋ ์ด '์ฐ๊ฒฐ' ์ฌ๋ถ๊ฐ ์ทจ์ฝ/๋น์ทจ์ฝ์ ๊ฐ๋๋ค.
PoC โฃ ๊ณต๊ธ๋ง ๊ฒ์ฆ โ '๋ฆด๋ฆฌ์ค tarball'๊ณผ 'git'์ ์ฐจ์ด ์ฐพ๊ธฐ
import difflib
# git ์ ์ฅ์์๋ ์๊ณ '๋ฐฐํฌ tar ํ์ผ'์๋ง ๋ค์ด์๋ ๋ณ์กฐ ๋ผ์ธ์ ์ฐพ์๋ด๋ ๊ฒ์ฆ (๋ชจ์)
git_version = """AC_DEFUN([AM_INIT_AUTOMAKE],
[ ... ์ ์์ ์ธ ๋น๋ ์ค์ ... ])
# (์ ์) ํน๋ณํ ์๋ ๋์ ์์"""
tarball_version = """AC_DEFUN([AM_INIT_AUTOMAKE],
[ ... ์ ์์ ์ธ ๋น๋ ์ค์ ... ])
# --- ์๋๋ tarball์๋ง ์กด์ฌํ๋ ์๋ ๋ผ์ธ (๋ฌธ์ํ๋ ์ค์ ํจํด์ ์ถ์ฝ) ---
gl_am_configmake=`grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/ 2>/dev/null`
xz -dc $srcdir/tests/files/good-large_compressed.lzma | sed ... > liblzma_la-crc64-fast.o"""
injected = [l for l in tarball_version.splitlines() if l not in git_version.splitlines()]
print("tarball์๋ง ์กด์ฌํ๋ ์์ฌ ๋ผ์ธ:", len(injected), "๊ฐ")
for l in injected:
print(" +", l.strip()[:72])
์คํ ๊ฒฐ๊ณผ(์ด๋ฒ ์คํ ์ค์ ์ถ๋ ฅ):
tarball์๋ง ์กด์ฌํ๋ ์์ฌ ๋ผ์ธ: 3 ๊ฐ
+ # --- ์๋๋ tarball์๋ง ์กด์ฌํ๋ ์๋ ๋ผ์ธ (๋ฌธ์ํ๋ ์ค์ ํจํด์ ์ถ์ฝ) ---
+ gl_am_configmake=`grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/ 2>/dev/null`
+ xz -dc $srcdir/tests/files/good-large_compressed.lzma | sed ... > liblzma_la-crc64-fast.o
6. ๋ฐฉ์ด ๋ฐฉ๋ฒ/๊ตํ โ ๋ฌด์์ ๋ฐฐ์ฐ๋
- '์ฝ์ ์ฝ๋'์ '๋น๋๋ ์ฝ๋'๊ฐ ๊ฐ๋ค๊ณ ๋ฏฟ์ง ๋ง๋ผ(์ต์ฐ์ ): ๋ฆฌ๋ทฐ๋ git ํธ๋ฆฌ๋ฅผ ๋ณด์ง๋ง, ์ค์ ๋น๋๋ ๋ฐฐํฌ tarball์ ๋ณธ๋ค. ๋ฆด๋ฆฌ์ค tarball๊ณผ git ํ๊ทธ์ ๋น๋ ์คํฌ๋ฆฝํธ๋ฅผ ์๋์ผ๋ก diffํ๊ณ , ๋ฐฐํฌํ์ upstream tarball์ ๊ทธ๋๋ก ์ ๋ขฐํ์ง ๋ง๊ณ ์ฌํ ๊ฐ๋ฅํ ๋น๋๋ก ๊ฒ์ฆํด์ผ ํ๋ค.
- ์ฌํ ๊ฐ๋ฅํ ๋น๋(Reproducible Builds): ์์ค์์ ๋์ผํ ๋ฐ์ด๋๋ฆฌ๊ฐ ๋์ค๋์ง ์ฌ๋ฌ ๋ ๋ฆฝ ํ๊ฒฝ์์ ๊ฒ์ฆํ๋ฉด ๋น๋ ์์ ์ฃผ์ ์ด ๋๋ฌ๋๋ค. DebianยทFedora๊ฐ ์งํ ์ค์ธ ์ด ํ๋ก์ ํธ๊ฐ ๋ฐ๋ก ์ด ์ฌ๊ฑด์ ๊ตฌ์กฐ์ ํด๋ฒ์ด๋ค.
- ๋น๋ ์์กด์ฑ๋ ์คํ ํ๋ฉด์ด๋ค: sshd์ liblzma๋ฅผ ๋์ด์ค๋ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ ํ๋๊ฐ ๊ณง ๊ณต๊ฒฉ ํ๋ฉด์ด์๋ค. ๋ถํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋งํฌ๋ฅผ ์ค์ด๊ณ , ๋คํธ์ํฌ ์๋น์ค ํ๋ก์ธ์ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ตฌ์ฑ์ ์ต์ํํ๋ผ.
- ์คํ์์ค '์ฌ๋' ๋ฆฌ์คํฌ ๊ด๋ฆฌ: ๊ด๋ฆฌ์ ๊ถํ์ด ํ ์ฌ๋์๊ฒ ์ง์ค๋๊ณ ์์ง๋๋ฉด ๊ณต๊ฒฉ์๊ฐ ์ฌํ๊ณตํ์ผ๋ก ๊ทธ ์๋ฆฌ๋ฅผ ๋์ฒดํ ์ ์๋ค. ๊ธฐ์ ยท์ฌ๋จ์ ์ ์ง๋ณด์์ ์ง์ยทํ๋ฉ๊ณผ ๋ค์ค ๊ด๋ฆฌ์ยท์๋ช ์ฒด๊ณ๊ฐ ์ค์ง์ ๋ฐฉ์ด๋ค.
- ๊ณต๊ธ๋ง SBOMยท์ํฐํฉํธ ์๋ช : ์ฌ์ฉ ์ค์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชฉ๋ก(SBOM)๊ณผ ๋ฆด๋ฆฌ์ค ์ํฐํฉํธ์ ๋ ๋ฆฝ ์๋ช ยทํฌ๋ช ์ฑ ๋ก๊ทธ(Sigstore ๋ฑ)๋ก '๋๊ฐ ๋ฌด์์ ์ธ์ ๋ง๋ค์๋'๋ฅผ ๊ฒ์ฆํ๋ค.
- '๋๋ฆฐ SSH'๋ ์ ํธ๋ค: ์ด์ํ์ง๋ ์ต์คํ๋ก์๋ง ์ก์ง ์๋๋ค. CPU ๊ธ์ฆยท์ง์ฐยทValgrind ๊ฒฝ๊ณ ๊ฐ์ ๋ฏธ์ธํ ์ฑ๋ฅ ์ด์์ด ์ต์ ์ ์ฌ๊ณ ๋ฅผ ๋ง์ ๋จ์์๋ค. ๊ธฐ์ ์ฑ๋ฅ๊ณผ ๋ฌด๊ฒฐ์ฑ์ ๋ชจ๋ํฐ๋งํ๋ผ.
- ์ ์ํ ๋กค๋ฐฑ ์ฒด๊ณ: ์ด๋ฒ์ ํ ๋ฌ ๋ง์ ๋ฐ๊ฒฌ๋ผ ํฐ ํผํด๊ฐ ์์๋ค. ๋ฐฐํฌํยท๊ธฐ์ ๋ชจ๋ ์ทจ์ฝ ๋ฒ์ ์ ์ฆ์ ์๋ณยท๋กค๋ฐฑยท์ฌ๋น๋ํ ์ ์๋ ์ ์ฐจ๋ฅผ ํ์์ ์ค๋นํด์ผ ํ๋ค.
7. ์ถ์ฒ
- Andres Freund โ oss-security: backdoor in upstream xz/liblzma leading to ssh server compromise (2024-03-29, ์ต์ด ๊ณต๊ฐ) โ openwall.com (oss-security)
- NIST NVD โ CVE-2024-3094 (CVSS 3.1 10.0, ๊ณต๊ฒฉ ๋ฒกํฐ) โ nvd.nist.gov/vuln/detail/CVE-2024-3094
- Red Hat โ Urgent security alert for Fedora Linux 40 and Fedora Rawhide users (2024-03-29) โ redhat.com
- Lasse Collin โ Remove the backdoor found in 5.6.0 and 5.6.1 (CVE-2024-3094) (์์ ์ปค๋ฐยท5.6.2 ๋ฆด๋ฆฌ์ค) โ github.com/tukaani-project/xz
- Wikipedia โ XZ Utils backdoor (ํ์๋ผ์ธยท์ํฅ ๋ฐฐํฌํยท์ฌํ๊ณตํ ์บ ํ์ธยท๊ท์ ๋ ผ์ ๊ฐ์) โ en.wikipedia.org/wiki/XZ_Utils_backdoor
- Andy Greenberg (Wired) โ The Mystery of 'Jia Tan,' the XZ Backdoor Mastermind โ wired.com
- Oxide Computer Company โ Oxide and Friends: Discovering the XZ Backdoor with Andres Freund (๋ฐ๊ฒฌ ๊ณผ์ ์์ธ) โ youtube.com
โป ๋ณธ๋ฌธ์ PoC ์ฝ๋๋ ๊ตฌ์กฐ ์ดํด ๋ชฉ์ ์ ๊ต์ก์ฉ ๋ชจ์ ์ฝ๋์ด๋ฉฐ, ์ค์ ๋ฐฑ๋์ด ํ์ด๋ก๋ยท์ค์ ์ค๋ธ์ ํธ ํ์ผยท ์ค์ Ed448 ์ฐํ ํคยท์ค์ OpenSSL ํํน ์ฝ๋๋ ํฌํจํ์ง ์์ต๋๋ค. ๋ชจ๋ ์ค์ต์ ์ธํฐ๋ท๊ณผ ๋ถ๋ฆฌ๋ ๊ฒฉ๋ฆฌ ๋ฉ VM์ ์ ์ ๋ก ํ๋ฉฐ, ์ค์ ์์คํ ยทํ์ธ ์์ฐ์ ๋ํ ์คํ์ ๋ถ๋ฒ์ ๋๋ค.
ํจ๊ป ์ฝ๊ธฐ: ๐ฆ SolarWinds SUNBURST (2020) โ ๊ณต๊ธ๋ง์ ๋ฌด๊ธฐ๋ก ์ ๋ขฐ๋ฅผ ๋ซ์ ๋ฐฑ๋์ด ยท ๐ Log4Shell (2021) โ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ ์ค์ด ๊ณต๊ธ๋ง์ ํ๋ ์ ๋ก๋ฐ์ด ยท Malware Deep-Dive: MOVEit / Cl0p (CVE-2023-34362) โ '์ ๋ขฐํ๋ ์ํํธ์จ์ด'๋ก ์กฐ์ง์ ๋๋ ์ ์ถ ยท โก Industroyer / CrashOverride โ ํ๋กํ ์ฝ์ ๊ทธ๋๋ก ๋งํ ์ฐ์ ์ ์ด ํ๊ดดํ ๊ณต๊ฒฉ