xz utils 2024年 配布物に仕込まれた裏口
2年かけて共同の保守者になった者が、裏口の本体を試験のファイルとしてリポジトリに入れ、それを起動する仕掛けを配布の束にだけ入れた。リポジトリを読んでも、束を読まずに信じても気付けない。止める所は、束とタグの差、ビルドの再現、入口に結ぶ依存の数にある。
要点
- 本体は、試験用の壊れた圧縮ファイルに見せかけてリポジトリに入っていた。起動する仕掛けは配布の束の中の m4 のファイルにだけあり、リポジトリには無かった。
- 束を作って署名したのは、2022年から共同の保守者として働いていた者だった。署名は、誰が作ったかを示すだけで、中身が安全なことを示さない。
- sshd に届いたのは、配布元が sshd に systemd への通知の当て布をして libsystemd を結び、その libsystemd が liblzma を結んでいたためである。
- 見つけたのは、ログインが遅い、valgrind が誤りを出す、という振る舞いの違和感だった。安定版の配布の多くに届く前に止まった。
- 根本の守りは、タグから作る、束とタグの差を確かめる、ビルドを再現できるようにする、入口のプロセスに結ぶ依存を減らす、の4つ。
何が起きたか
| 日付 | 出来事 |
|---|---|
| 2021年10月29日 | Jia Tan の名前で、xz-devel の一覧に最初の修正案が届く。.editorconfig を足すだけの小さな案[9] |
| 2022年6月7日 | 一覧に、新しい保守者が来るまで進まない、今の保守者は関心を失った、という投稿が届く[10] |
| 2022年6月8日 | 保守者の Lasse Collin が返信する。無償の趣味の作業で、長く続く心の不調などで手が回らないこと、Jia Tan と一覧の外で作業しており、より大きな役割を持つかもしれないことを書く[11] |
| 2022年6月29日 | Lasse Collin が、Jia Tan は実質的にすでに共同の保守者だと書く[12] |
| 2022年11月30日 | README の連絡先が、保守者 Lasse Collin と Jia Tan の2人に届く宛先に変わる[13] |
| 2023年3月18日 | 5.4.2 のタグを Jia Tan が付けて署名する[14] |
| 2024年2月23日 | Jia Tan が、試験用のファイルを足すコミットを入れる。この中に本体が隠されていた[15][1] |
| 2024年2月24日 | 5.6.0 を出す[16]。束は Jia Tan が作り、署名した[2] |
| 2024年3月9日 | 5.6.1 を出す[16] |
| 2024年3月29日 | Andres Freund が oss-security の一覧に公表する[1]。Red Hat が CVE-2024-3094 を割り当て、NVD に載る[3]。CISA、Debian、Red Hat、openSUSE が同じ日に告知を出す[4][6][7][8] |
| 2024年4月1日 | JPCERT/CC が CyberNewsFlash で注意を呼びかける[5] |
| 2024年5月29日 | 開発元が、点検の記録の1.0版と、裏口を除いた 5.6.2 を出す[2][16] |
- Jia Tan が触れられたのは GitHub に置いた物だけで、tukaani.org の本体のサイトと git.tukaani.org のリポジトリには Lasse Collin だけが触れられた、と開発元は書く[2]。束を GitHub から配っていたため、これで足りた。
- 保守の交代を迫った投稿者が何者かは、開発元も公的機関も公表していない。
通った道筋
| 段 | 何があったか |
|---|---|
| リポジトリ | 本体の大部分は、難読化した試験のファイルとして git に入っていた[1]。2024年2月23日のコミットは、壊れた xz や lzma の試験のファイルを足すという名目だった[15]。5.6.0 では、これらのファイルはどの試験にも使われていなかった[1]。開発元は、これらのファイルは、git に一度も入らなかった起動の仕掛けが無ければ害が無いと書く[2]。 |
| 配布の束 | 束の m4/build-to-host.m4 に、configure の終わりで難読化したスクリプトを走らせる行が足されていた。この行は元にした m4 の上流には無く、xz の git ではこの m4 を使っていない[1]。束は Jia Tan が作り、自分の鍵で署名していた[2]。 |
| 配布元のビルド | 仕掛けが働くのは、x86-64 の Linux で、GCC と GNU のリンカを使い、Debian か RPM の包みを作るビルドの中だけだった[1]。NVD の説明では、偽装した試験のファイルから作り置きのオブジェクトを取り出し、liblzma の特定の関数を書き換える[3]。 |
| 実行時 | OpenSSH の上流は liblzma を使わない。Debian ほか複数の配布元は、systemd への通知のため sshd に当て布をしており、libsystemd が liblzma に依存していた[1]。こうして root で動く sshd の中に、改変した liblzma が読み込まれた。 |
本体は読めない2進のファイルで、起動の仕掛けは git に無い。コードを差分で読む点検は、どちらも拾えない。git を読む人は束を見ず、束を取り込む人は git との差を見ない。その隙間に置かれた。
どう見つかったか
見つけたのは Andres Freund である。Debian の開発版の sid で、数週間にわたり ssh のログインが CPU を多く使い、valgrind が誤りを出すことに気付き、perf と gdb で追った[1]。
- 差は0.5秒ほどで、利用者が体感で気付く大きさではない。同じ機械で同じ操作を測り続けていたから、違いとして見えた。
- valgrind の誤りと一部の環境での異常終了は、裏口が想定したスタックの配置と実際が違うために起きていた。5.6.1 では、この誤りを直すという名目の変更が入った。開発版で試験を回していたことが、2つ目の手がかりになった[1]。
- Freund の公表の時点で、5.6.0 と 5.6.1 はほとんどの配布元の安定版に入っておらず、入っていても多くは試験版だった[1]。
影響と配布元の対応
| 配布元 | 影響を受けた版 | 対応 |
|---|---|---|
| Debian | testing、unstable、experimental の 5.5.1alpha-0.1 から 5.6.1-1。安定版は影響が知られていない[7] | 上流の 5.4.5 の中身に戻した 5.6.1+really5.4.5-1[7] |
| Fedora | Rawhide と Fedora Linux 40 の試験版。RHEL はどの版も影響なし[6] | Rawhide の利用をすぐ止め、5.4 系へ下げる[6] |
| openSUSE | Tumbleweed と MicroOS に3月7日から28日まで。Leap と SLE には無い[8] | 20240328 以降の版へ上げて再起動。ssh を外へ開いていたなら入れ直し、資格情報を全部回す[8] |
| 全般 | XZ Utils 5.6.0 と 5.6.1 | CISA は 5.4.6 のような侵害の無い版へ下げ、侵害の跡を探すよう勧めた[4] |
版の確かめ方 包みの管理の命令で見る
dpkg -l xz-utils liblzma5 # Debian 系
rpm -q xz-libs # Fedora 系
rpm -q liblzma5 # openSUSE
xz --version # 疑わしい版を自分で動かすことになる
JPCERT/CC は、侵害された版を使っている恐れがあるため、xz の命令で版を確かめず、包みの管理の命令を使うよう求めた[5]。openSUSE は、裏口の作りが巧みで、入ったかどうかを機械の上で見つけるのはおそらくできないと書いた[8]。疑わしい版を動かしていた機械は、調べて安心するより、入れ直して鍵を回す方を先にする。
どこで止められたか
| 止める所 | この件で | 限り |
|---|---|---|
| 保守者を1人にしない | 保守者は1人で、無償で、手が回らないと一覧に書いていた[11]。そこへ交代を迫る投稿が重なり、手伝いを申し出た者が共同の保守者になった[10][12] | 人を増やしても、増えた人が悪意を持てば同じ。権限を渡す前の確かめと、1人で版を出せない形が要る |
| 束とタグの差を見る | m4 の変更は git に無く、束にだけあった[1]。比べれば差として出た | autotools の束は生成物を含むので、差がもともと多い。生成物を作り直してから比べる |
| タグから作り、再現する | GitHub が自動で作るソースの束には、この行が無かった[1]。タグから作っていれば仕掛けは働かない | 本体は git にあった。git の中身を信じる限り、次の手口では git に入れられる |
| 入口に結ぶ依存を減らす | 上流の OpenSSH は liblzma を使わない。配布元の当て布で sshd に届いた[1] | 依存を減らすのは届く道を減らすだけで、部品の悪意を消さない |
| 振る舞いの違いを測る | ログインの0.5秒の遅れと valgrind の誤りで見つかった[1] | 偶然に近い。遅れが出ないよう作られていたら見つからなかった |
この件のあと、上流の側でも入口の依存が減った。OpenSSH 9.8 は2024年7月1日に、libsystemd に依存しない独自の実装で systemd へ通知する機能を入れた[17]。systemd 256 は、liblzma などを、ふつうの共有ライブラリの依存から、要るときに dlopen で読む形に変えた[18]。
守り方
- 部品は、配布の束ではなく署名したタグから作る。束を使うときは、同じ版のタグと中身を比べ、git に無い変更があれば取り込まない。
- ビルドを再現できるようにする。再現できるビルドとは、同じソース、同じ環境、同じ手順から、誰が作っても全部の成果物がビット単位で同じになることを言う[19]。作った人と別の人が作って一致を確かめれば、1人の作る人に裏切られても気付ける。
- 版は意図して選んで固定し、出たばかりの版を本番に入れない。この件の版は、配布元の開発版と試験版にしか届かなかった[1]。
- 認証の入口になるプロセスに結ぶ依存を減らす。sshd のような root で外を待ち受けるプロセスが、何の共有ライブラリを読み込んでいるかを
lddで棚卸しし、要らない物を外す。 - 自社が頼る部品の保守の体制を見る。保守者が1人か、無償か、急に新しい人が権限を得ていないか。頼るなら、資金か人で支える。
束とタグを比べる 架空の部品 libfoo 2.1.0
curl -sO https://downloads.example.com/libfoo/libfoo-2.1.0.tar.gz
tar xzf libfoo-2.1.0.tar.gz
git clone --quiet --branch v2.1.0 https://git.example.com/libfoo.git libfoo-tag
git -C libfoo-tag verify-tag v2.1.0 # タグの署名を確かめる
autoreconf -fi libfoo-tag # 生成物をタグから作り直す
diff -r -q --exclude=.git libfoo-tag libfoo-2.1.0
# 出力
Files libfoo-tag/m4/build-helper.m4 and libfoo-2.1.0/m4/build-helper.m4 differ
Only in libfoo-2.1.0: ChangeLog
- 生成物は autotools の版で変わるので、差がすべて悪意とは限らない。差が出たファイルを1つずつ読み、説明の付かない差があれば、その束は使わない。
- 比べて差を読む手間がかかるなら、束を使わずタグから作る方が早い。署名は、作った人を確かめる手段で、中身の安全の証明ではない。この件の束も、保守者の鍵で正しく署名されていた[2]。
AIが書く依存の変更
AIのコーディングの道具は、依存の版を上げ、ロックファイルを書き換え、試験のファイルを足す差分を、ためらわずに作る。この件の2つの入口は、どちらもその差分の形をしていた。
- 試験のファイルを足すコミットは、2進のファイルの追加だけで、コードの差分として読める所が無い[15]。AIに差分を点検させても、2進のファイルの中身は読まれない。作り方を説明できない2進のファイルは、誰が足したかに関わらず止める。
- 版を上げる差分は、版の数字とハッシュが変わるだけに見える。新しい版の束とタグの差、保守者の交代、公開からの日数は、差分に現れない。AIが出した版の上げは、人がその版の出どころを確かめてから入れる。
- 存在しない部品の名前を先に登録される型と、足す差分で止めて確かめる手順は、AIが持ち込む部品の危険で扱う。
型としての整理は A03 ソフトウェアサプライチェーンの不備 の型2と型3に当たり、取り込む物を使う直前に確かめる考え方は A08 ソフトウェアまたはデータの完全性の不備 にある。
参照
- backdoor in upstream xz/liblzma leading to ssh server compromise Andres Freund、oss-security、2024年3月29日
- XZ Utils backdoor Lasse Collin、tukaani.org、2025年1月17日更新
- CVE-2024-3094 NIST NVD
- Reported Supply Chain Compromise Affecting XZ Utils Data Compression Library, CVE-2024-3094 CISA、2024年3月29日
- XZ Utilsに悪意のあるコードが挿入された問題 CVE-2024-3094 について JPCERT/CC CyberNewsFlash、2024年4月1日
- Urgent security alert for Fedora Linux 40 and Fedora Rawhide users Red Hat、2024年3月29日
- DSA 5649-1 xz-utils security update Debian、2024年3月29日
- openSUSE addresses supply chain attack against xz compression library openSUSE、2024年3月29日
- PATCH xz: Added .editorconfig file for simple style guide encouragement xz-devel、2021年10月29日
- Re: XZ for Java xz-devel、2022年6月7日
- Re: XZ for Java Lasse Collin、xz-devel、2022年6月8日
- Re: XZ for Java Lasse Collin、xz-devel、2022年6月29日
- Change the bug report address tukaani-project/xz、2022年11月30日のコミット
- v5.4.2 tukaani-project/xz、2023年3月18日のタグ
- Tests: Add a few test files tukaani-project/xz、2024年2月23日のコミット
- NEWS tukaani-project/xz
- OpenSSH 9.8 release notes OpenSSH、2024年7月1日
- systemd NEWS CHANGES WITH 256 systemd、2024年6月
- Definitions Reproducible Builds