
2026/03/29 1:59
「Linuxはインタープリタです。」
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
要約
この記事では、
https://astrid.tech/rkx.gz からダウンロードされる rkx と呼ばれる悪意のあるシェルスクリプトを解剖しています。スクリプトが root 権限で実行され、
kexec、base64、cpio のユーティリティがインストールされていることを確認した後、スクリプトは以下の手順を踏みます。
- 埋め込まれた base‑64 バイト列を r というファイルにデコードし、その r から cpio アーカイブを抽出して実行可能なカーネルイメージ k を作成します。
を実行した後、kexec --load k --initrd r --reuse-cmdline
を呼び出し、システムをデコードされたラムディスクとともにこの新しいカーネルへ再起動させます。kexec --exec- 抽出された initramfs 内で、シェルスクリプトが
をマウントし、すべてのファイル(ただし/proc
と自身以外)を含む新しい cpio イメージ /r を構築します。その後、再度/proc
を実行します。kexec --load /k --initrd /r
この再帰的な kexec チェーンは、各カーネルが前の initramfs から次をロードする無限ループを作り出し、Linux に対する「tail‑call 最適化」のように機能します。
さらに記事では、cpio アーカイブは通常実行可能ではありませんが、
binfmt_misc がマジック文字列 \x30\x37\x30\x37\x30\x31 を含むファイルのインタープリターを登録すると実行できることを説明しています。QEMU ベースのスクリプト(qemu-system-x86_64)がこのインタープリターとして機能し、各実行時に新しい Linux カーネルを仮想化します。
攻撃を簡略化するために、著者は再帰ループを単一の kexec‑only インタープリター(
/bin/cpio-interpreter)に置き換えることを提案しています。これは binfmt_misc を介して登録されます。インタープリタバイナリが静的リンクであるため、カーネルは最終的にそれを直接実行し、無限再帰を防ぎつつ自己複製を可能にします。
この記事の結論として、この構造は initramfs 用の「クァイン」に相当すると述べています。すなわち、メモリ上で自身を再生成し、同一環境へ再起動する initrd です。これは企業向け Linux デプロイメントにおいて、
kexec、binfmt_misc の登録、および initramfs ハンドリングへのより厳格な制御が必要であることを強調しています。本文
概要 – クリーンアップ済み&構造化
1. マルウェアの動作
- root権限と必要ツール(
、kexec
、base64
)を確認。cpio - 大きなBase‑64データを解読し、アーカイブ
を生成。r - そのアーカイブから Linux カーネルイメージ
を抽出。k
を呼び出してカーネル(kexec
)をロードし、k
を initrd として実行。r
2. initrd 内の内容
#!/bin/sh mkdir -p /proc mount -t proc proc /proc # /proc と /r を除く全てで新しい cpio(/r)を作成 find / | grep -v /r | grep -v /proc | cpio -vo -H newc > /r # 実行中のカーネルを /r を initrd として再ロード kexec --load /k --initrd /r --reuse-cmdline kexec --exec
- スクリプトは 再帰的に 新しいカーネルを読み込み、システムが自らへとリブートし続ける ― tail‑call 再帰の一種。
3. なぜこれが クワイン なのか
クワインとは、自身の正確なコピーを出力するプログラムである。
initrd の
init スクリプトを次のように変更すれば、クワイン化できる。
kexec --load /k --initrd /r ...
↓
cat /r # 実行ではなく出力する
/r はこの initrd を含む cpio なので、実行すると同じアーカイブが再度出力され、自己複製型 Linux 環境になる。
4. binfmt_misc
による非 ELF ファイルの実行
binfmt_miscLinux は ハンドラ が登録されていれば任意ファイルタイプを実行できる。
echo ':cpio:M::\x30\x37\x30\x37\x30\x31::/path/to/script.sh:' \ > /proc/sys/fs/binfmt_misc/register
これによりスクリプトは QEMU を起動し、カーネルをブートしてアーカイブを initrd として扱い、initrd 自体をプログラムとして実行できる。
5. 再帰スタック
- 各
は現在のカーネルを置き換えるため スタックは積み上がらない。kexec - 新しいカーネルは新たなメモリ空間で走るので、古いフレームは残らない。
- これは tail‑call 最適化済み再帰 ― インタプリタ(=カーネル)が前のフレームを解放する必要がない。
6. キー概念と示すもの
| 概念 | 示す内容 |
|---|---|
| initrd | カーネルをブートできる RAM ディスク。 |
| kexec | 実行中のカーネルを即座に別イメージへ置き換える。 |
| クワイン | 自身を出力する initrd(インタプリタの定数点)。 |
| binfmt_misc | 登録ハンドラで Linux が任意ファイルタイプを実行可能。 |
| Tail‑call 再帰 | カーネル再ロードでスタックが増えない再帰。 |
速攻リファレンス – 再帰的 initrd 用 Bash スニペット
#!/bin/sh set -x mkdir -p /proc mount -t proc proc /proc # /proc と自身を除いた新しい cpio(/r)を作成 find / | grep -v /r | grep -v /proc | cpio -vo -H newc > /r # CPIO ファイル用ハンドラを登録 echo ':cpio:M::\x30\x37\x30\x37\x30\x31::/bin/cpio-interpreter:' \ > /proc/sys/fs/binfmt_misc/register chmod +x /r exec /r # これが新しい init プロセスになる
は /bin/cpio‑interpreter
を initrd として再度 /r
するだけのシンプルなスクリプトです。kexec
クリーンアップ完了。