1 ポイント 投稿者 GN⁺ 2 시간 전 | 1件のコメント | WhatsAppで共有
  • PyPI lightning 2.6.22.6.3 が2026年4月30日に公開された後、サプライチェーン攻撃に悪用され、pip install lightning だけで隠された _runtime ディレクトリと難読化された JavaScript ペイロードが実行される可能性がある
  • 悪性ペイロードはモジュールのインポート時に自動実行され、認証情報、認証トークン、環境変数、クラウドシークレットを窃取し、GitHub リポジトリの汚染も試みる
  • 今回の攻撃は侵入口が PyPI だが、ワームの拡散は npm を通じて行われ、npm 公開資格情報が見つかると、公開可能なパッケージに setup.mjs ドロッパーと router_runtime.js を注入し、パッチバージョンを再公開する
  • データ流出には HTTPS POST、GitHub コミット検索のデッドドロップ、攻撃者管理の公開 GitHub リポジトリ、被害者リポジトリへの直接プッシュという 4つの並列チャネル が使われ、EveryBoiWeBuildIsAWormyBoi コミット接頭辞と "A Mini Shai-Hulud has Appeared" リポジトリ説明が指標として残る
  • マルウェアは Claude Code.claude/settings.json にある SessionStart フックと、VS Code.vscode/tasks.json にある runOn: folderOpen タスクを埋め込み、リポジトリを開くたびにドロッパーを実行し、影響期間中に悪性パッケージをインポートしたマシンは完全に侵害されたものとして扱うべきである

影響を受けるパッケージと確認手順

  • lightning は、画像分類器の構築、LLM のファインチューニング、拡散モデルの実行、時系列予測器の開発チームの依存関係ツリーに頻繁に含まれるディープラーニングフレームワークである
  • 影響を受けるパッケージ

    • lightning バージョン 2.6.2
    • lightning バージョン 2.6.3
  • Semgrep 顧客向け確認手順

    • 最近プロジェクトスキャンを実行していない場合は、新しいスキャンを実行する必要がある
    • advisories ページ で、プロジェクトが該当パッケージバージョンを最近インストールしたか確認できる
    • dependency filter で一致項目を確認でき、「No matching dependencies」と表示される場合、そのプロジェクトでは悪性依存関係をアクティブには使用していないことを意味する
    • 一致項目がある場合は、以下の侵害指標にある .claude/.vscode/ ディレクトリ内の予期しないファイルをリポジトリで監査する必要がある
    • 影響を受けた環境に存在した可能性のある GitHub トークン、クラウド認証情報、API キーをローテーションする必要がある
    • サプライチェーン攻撃への対応と待機期間に関する一般的な助言は $foo compromised in $packagemanagerAttackers are Still Coming for Security Companies で扱っている

PyPI から npm に拡散する構造

  • mini Shai-Hulud が npm を直接狙っていたのとは異なり、今回の攻撃の侵入口は PyPI である
  • 悪性ペイロードは依然として JavaScript であり、ワームの拡散は npm を通じて発生する
  • 実行されたマルウェアが npm 公開資格情報を見つけると、そのトークンで公開可能なすべてのパッケージに setup.mjs ドロッパーと router_runtime.js を注入する
  • その後、scripts.preinstall をドロッパー実行に設定し、パッチバージョンを上げて再公開する
  • そのパッケージをインストールした下流の開発者は、自分のマシンで完全なマルウェアを実行することになり、トークン窃取とパッケージワーム感染が続く

データ流出方式

  • 窃取機能は以前のキャンペーンの Mini Shai-Hulud のメカニズムと設計を共有しており、個別の経路が遮断されてもデータが流出するよう、4つの並列チャネルを使用する
  • 攻撃には EveryBoiWeBuildIsaWormBoi という公開リポジトリ作成など、Shai-Hulud テーマが含まれる
  • 攻撃指標の構造は以前の mini Shai-Hulud キャンペーンと一致しており、悪性コミットメッセージは EveryBoiWeBuildIsAWormyBoi 接頭辞を使って、元の Mini Shai-Hulud 攻撃と区別される
  • HTTPS POST による C2 転送

    • 窃取データはポート443経由で攻撃者管理サーバーへ即座に POST される
    • ドメインとパスはペイロード内に暗号化された文字列として保存され、静的解析を困難にしている
  • GitHub コミット検索デッドドロップ

    • マルウェアは GitHub コミット検索 API をポーリングし、EveryBoiWeBuildIsAWormyBoi 接頭辞付きのコミットメッセージを探す
    • コミットメッセージは EveryBoiWeBuildIsAWormyBoi:<base64(base64(token))> 形式の二重 Base64 エンコードされたトークンを運ぶ
    • デコードされたトークンは、その後の操作のための Octokit クライアント認証に使われる
  • 攻撃者管理の公開 GitHub リポジトリ

    • ランダムに選ばれた Dune の単語名と "A Mini Shai-Hulud has Appeared" という説明を持つ新しい公開リポジトリが作成される
    • この説明は GitHub 上で直接検索できる
    • 窃取された認証情報は results/results-<timestamp>-<n>.json としてコミットされ、API 経由では Base64 エンコードされるが内部は通常の JSON である
    • 30MB を超えるファイルは番号付きチャンクに分割される
    • コミットメッセージは偽装のため chore: update dependencies を使用する
  • 被害者リポジトリへの直接プッシュ

    • マルウェアが ghs_ GitHub サーバートークンを取得すると、被害者の GITHUB_REPOSITORY の全ブランチに窃取データを直接プッシュする

窃取対象

  • マルウェアはローカルファイル、環境、CI/CD パイプライン、クラウドプロバイダー全般の認証情報を狙う
  • ファイルシステム

    • 80以上の認証情報ファイルパスをスキャンし、ghp_gho_npm_ トークンを探す
    • ファイルごとに最大 5MB まで処理する
  • シェルと環境変数

    • gh auth token を実行する
    • process.env のすべての環境変数をダンプする
  • GitHub Actions

    • Linux ランナー上で内蔵 Python を使い、Runner.Worker プロセスメモリをダンプする
    • "isSecret":true とマークされたすべてのシークレットと、GITHUB_REPOSITORYGITHUB_WORKFLOW を抽出する
  • GitHub 組織

    • トークンスコープ repoworkflow を確認する
    • GitHub Actions の組織シークレットを列挙する
  • AWS

    • 環境変数、~/.aws/credentials プロファイル、IMDSv2 169.254.169.254、ECS 169.254.170.2 を試して sts:GetCallerIdentity を呼び出す
    • Secrets Manager のすべての値と SSM パラメータを列挙して取得する
  • Azure

    • DefaultAzureCredential を使用してサブスクリプションを列挙し、Key Vault シークレットにアクセスする
  • GCP

    • GoogleAuth で認証する
    • Secret Manager のすべてのシークレットを列挙して取得する
    • 対象範囲にはローカル開発環境、CI ランナー、主要3大クラウドプロバイダーのすべてが含まれる
    • 影響を受けた期間に悪性パッケージをインポートしたすべてのマシンは、完全に侵害 されたものとして扱うべきである

開発ツールを通じた永続化の確保

  • リポジトリ内部に入った後、マルウェアはよく使われる開発ツールである Claude CodeVS Code を狙って永続化フックを埋め込む
  • Claude Code

    • マルウェアはリポジトリの Claude Code 設定ファイル .claude/settings.json に、matcher: "*"SessionStart フックを書き込む
    • フックは node .vscode/setup.mjs を指す
    • 開発者が感染したリポジトリで Claude Code を開くたびに実行され、セッション開始以外のツール使用やユーザー操作は不要である
  • VS Code

    • VS Code ユーザーを狙い、.vscode/tasks.jsonrunOn: folderOpen タスクを埋め込む
    • プロジェクトフォルダが開かれるたびに node .claude/setup.mjs が実行される
  • ドロッパー setup.mjs

    • どちらのフックも、自己完結型の Bun ランタイムブートストラッパーである setup.mjs を呼び出す
    • Bun がインストールされていない場合、GitHub Releases から bun-v1.3.13 を静かにダウンロードする
    • Linux x64、Linux arm64、Linux musl、macOS x64、macOS arm64、Windows x64、Windows arm64 を処理する
    • その後、完全な 14.8MB ペイロードである .claude/router_runtime.js を実行し、/tmp からクリーンアップする
  • 悪性 GitHub Actions ワークフロー

    • マルウェアが書き込み権限のある GitHub トークンを持っている場合、被害者リポジトリに Formatter というワークフローをプッシュする
    • すべての push で ${{ toJSON(secrets) }} を通じてすべてのリポジトリシークレットをダンプする
    • 結果を format-results というダウンロード可能な Actions アーティファクトとしてアップロードする
    • Actions は正常に見せるため、特定のコミット SHA に固定される
    • CI で感染した lightning パッケージを受け取り、書き込み権限トークンを持つリポジトリは、それらのファイルを監査する必要がある

侵害指標

  • 検索可能な指標

    • EveryBoiWeBuildIsAWormyBoi 接頭辞付きのコミットメッセージはデッドドロップトークン運搬手段として使われ、GitHub コミット検索で見つけられる
    • "A Mini Shai-Hulud has Appeared" という説明を持つ GitHub リポジトリは攻撃者の流出用リポジトリであり、直接検索可能である
  • パッケージ

    • lightning@2.6.2
    • lightning@2.6.3
  • ファイルとシステムアーティファクト

    • _runtime/start.py: インポート時にペイロードを初期化する Python ローダー
    • _runtime/router_runtime.js: 難読化された JavaScript ペイロードであり、14.8MB の Bun ランタイム
    • _runtime/: 悪性パッケージバージョンに追加されたディレクトリ
    • .claude/router_runtime.js: 被害者リポジトリに注入されたマルウェアのコピー
    • .claude/settings.json: 被害者リポジトリに注入された Claude Code フック設定
    • .claude/setup.mjs: 被害者リポジトリに注入されたドロッパー
    • .vscode/tasks.json: 被害者リポジトリに注入された VS Code 自動実行タスク
    • .vscode/setup.mjs: 被害者リポジトリに注入されたドロッパー

1件のコメント

 
GN⁺ 2 시간 전
Hacker Newsの反応
  • 単なる頻度の錯覚かもしれないが、最近は主要パッケージで有名なサプライチェーン攻撃がかなり多く見られる
    今のHNの最初の数ページを見ても、別々の事例を扱った投稿がいくつもある
    10年前のleft-padを振り返ると、今は成功した攻撃が当時より増えているのではと思うし、おそらくその通りだろう
    成功した攻撃の価値も確実に大きくなっているはずだが、パッケージのリリース前に検知する能力が、コミュニティ全体として実際に向上しているのか気になる
    商用ソフトウェア企業はもっとうまくやるべきだが、趣味・アマチュアのコードとして始まり、その後多くのプロジェクトの依存先になるようなケース向けの、汎用的で簡単なツールはまだ不足しているように見える
    今のSAPサプライチェーン攻撃スレッドにも同じコメントを投稿した: https://news.ycombinator.com/item?id=47964003

    • 実際に起きている現象だ。4月初め時点で、直近12か月に7件あり、その前の20年間では9件だった: https://www.jefftk.com/p/more-and-more-extensive-supply-chai...
    • 人々がコードをきちんと見もせず、あちこちに大量投入しているのだから、それに応じてサプライチェーン攻撃が増えるのは自然なことだ
    • 理由は自動更新とCIツールの普及率が臨界点に達し、みんなが使うようになったからだ
      以前はnpm installを手動で実行することがもっと多く、ビルドが壊れたときか、せいぜいたまに実行する程度だったはずだ
      サプライチェーン攻撃は、人間が、より正確にはパイプラインが、新しいリリースが出るやいなや何も考えずにパッケージを自動更新することに依存している
    • 歴史的に見て、追加のセキュリティ検査を経た成果物の取り扱いは有料のエンタープライズ向けオプションであり、より安全でない側が、はるかに面倒の少ないデフォルトだった
      これが良いビジネスモデルかは分からないし、たぶんそうではないだろう
    • left-padは攻撃ではなく、NPMのバグだった
      すでに公開されていて、別のパッケージが依存しているパッケージバージョンを削除できてはいけなかったし、逆に新しいバージョンで、まだ誰も依存していない特定のパッケージバージョンは削除できるべきだった
      left-padの作者がサービスを離れる意図ですべてのデータを消そうとしたとき、NPMはエラーコードを返すべきだった
      Wikipediaによると、Koçuluがnpm, Inc.の決定に失望し、プラットフォームの一部として残りたくないと述べた際、NPM作者のSchlueterが、彼が登録した273個のモジュールを削除するコマンドを提供したという
  • 奇妙なのは、4件のセキュリティ問題が上がったのに、どれもpl-ghostというボットが自動コメントを付けて閉じていたことだ [1][2][3][4]
    結局、このうち[4]だけがきちんと処理され、ボットのコメントはすべて削除された
    別のレポート[5]ではそのボットコメントを見ることができ、元記事より多くの情報を与えている
    [1] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [2] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [3] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [4] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [5] https://socket.dev/blog/lightning-pypi-package-compromised

    • LightningのAndyです。そうです、PyPI認証情報はpl-ghostボットアカウントの侵害を通じて盗まれました
      攻撃者はこのアカウントで新しいActionsワークフローを作成し、実行されたワークフローからPyPIシークレットをパースして抜き取りました
      パッケージをリリースした後は、そのアカウントでコメントを投稿し、こちらを少しあざ笑っていました
  • 依存関係がまったくない日が早く来てほしい
    極端な例として、最近は娘のためのインタラクティブな教育アプリを作るとき、Opusに純粋なJavaScriptとHTMLだけを使わせている
    二重振り子から流体シミュレーションまで一発でうまく動き、昔なら依存関係が数百個あったはずだ
    MITライセンスのコードなら、Opusに必要な部分だけを正確に抽出し、自分の用途向けに修正して組み込ませることもできる
    趣味プロジェクトでは今のところうまくいっていて、今後は本番ソフトウェアでも依存関係がなくなってほしい

    • そうすると、あらゆる変更や無数の例外を全部自分で管理しなければならない
      ChromeがあるAPIの形を変えたら自分で見つけて直す必要があるし、モロッコが夏時間の開始時期を変えたら日時処理コードも自分で更新しなければならない
      こうしたことは、ライブラリが代わりに処理してくれるから当たり前だと思っていた部分だ
      娘が来週には興味を失うような二重振り子シミュレータなら大したことではないが、今後無期限に動き続けるものを作る会社にとっては問題になる
    • これで真の依存先であるブラウザにさらされることになる
    • もちろん、Opusが生成したコードの全行を、オープンソースメンテナに期待するのと同じ水準で丁寧にレビューするんだよね? そうだよね?
      MITライセンスのリモートアクセスコードを1つ公開して、Opusの学習データに入るようにしてみるべきだな
    • RustをGoより好んでいるので悩ましい。LLMの観点でもRustの方が良いが、Rustの依存関係の哲学は実質的にセキュリティブラックホールで、Goの方がずっとましだ
    • 共有できるリポジトリやforgeに置いてあるものはある? 農場の動物のスペル当てゲームがあるので、自分のライブラリを拡張してアイデアを増やしたい
  • Fast.AIのディープラーニング講座を受けたとき、機械学習プロジェクトが引き込むPython依存関係の数に驚いた
    Webフロントエンドのプロジェクトは常にサードパーティ依存が多いと思っていたが、自分には機械学習エコシステムの方がはるかに絡み合って見える
    しかもWeb開発はセキュリティに敏感だと見なされ、長年にわたりセキュリティの知見や慣行が蓄積されてきたが、機械学習開発はずっと場当たり的で、一般的なソフトウェア工学の慣行もあまり適用されていないように思える
    たとえば当時、機械学習モデルの配布方法の1つがPython pickleだったが、これは基本的に制限のない実行可能オブジェクトだ
    この形式のモデルは、取り込むコンピュータ上で何でもできてしまい、この初期の無法地帯のようなエコシステムがセキュリティ侵害やサプライチェーン攻撃をより容易にしている可能性がある

    • そのエコシステムには、もともとソフトウェアエンジニアではない人が多い
      やっているうちに少しコーディングを覚えた人もいれば、数学者もいるし、AIに酔った開発者のような人もいる
      「コードはもう重要ではなく、動けばいい」という考え方もある
      多くの人にとって、まともな依存関係管理は気にしたくない雑務にすぎない
      いくつもの機械学習プロジェクトでこうした要素が重なっているが、実際には機械学習プロジェクトこそ再現性に最も注力すべき分野の1つだ
  • リポジトリ検索を見たところ、過去24時間に作成されたリポジトリのうち、"A Mini Shai-Hulud has Appeared"というテキストを含むものが2.2千件もある: https://github.com/search?q=A%20Mini%20Shai-Hulud%20has%20Ap...

    • リポジトリ名はすべてduneの2つの用語・単語、たとえばharkonen、mentat、ornithoptorのようなものに数字が付いた形に見える
      これはアカウント、たぶんGitHub認証/Actionsトークンが侵害された後、それを使ってリポジトリが作成されたことを示すサインに見える
    • https://github.com/tinin46 このアカウントは大量のキーを保存しているように見えるが、用途はよく分からない
    • GitHubがすぐに対応して、READMEが正規表現に一致するリポジトリをブロックできない理由が分からない
      前回もこういうことがあったのだから、教訓を得ていたはずだと思っていた
      このマルウェアはあまり努力しておらず、Microsoftもあまり努力していないように見える
    • いったい何が起きているんだ?
  • 免責すると、pytorchを使ったことはないし、ソフトウェアセキュリティの慣行にも詳しくない
    だが、pytorchでネットワークアクセスが必要になるシナリオがあまり思い浮かばない
    コードベースのどこででも任意のモジュールをimportしてそのAPIを使えるのは、まずいように思える
    追加のimport制限や静的解析が必要そうだ
    言語がこういう問題を扱うための適切な抽象化を持っていないように思う
    比較すると、Rustでは関数シグネチャを見るだけで内部コードを理解しなくても可変性やライフタイムが分かるのが良い
    依存関係にも似たものが必要だと感じる
    開発者は下位コードをのぞかなくても、すべての依存関係を簡単に監査して、「ああ、この依存関係はeval()を使っているな」とか「ネットワークアクセスしているな」と分かるべきだ
    モバイルアプリは権限を強制するのだから、開発者も特定の機能だけを許可リストに入れ、あらゆる機能を丸ごと受け入れずに済むべきではないか

    • Pythonエコシステムでは、こういうことは絶対に受け入れられないだろうが、この話題がその中でよりよく理解され、認識されてほしい
      一般化はしたくないが、とくにAI開発コミュニティは、他のあらゆる考慮よりも利便性を優先しているように見える
      たとえば、プロジェクトが初回実行時に大きなモデルを自動ダウンロードするのが標準のようになっている
      たいてい無効化はできるが、複数ライブラリにまたがるコードクラスの深い階層のせいで、正しいパラメータを見つけるのが本当につらい
      複雑なものを、たいていはおもちゃに近いものを、あまりに簡単に始められるのは良いことだが、この許容的な空気はかなり居心地が悪い
      最初の問題解決ステップがいつも「pip install …」であるように思えるし、一部の環境、たとえばMacOSではGPUアクセスの仮想化もうまくいかない
    • 複数のコンピュートノードにまたがってモデルを学習させるケースがある。それはネットワークアクセスが必要になる大きな例だ
  • 今週、Pythonのバージョン管理にuvを使うのが良い考えなのか気になっていた
    Webサイト[1]には「Pythonは公式な配布用バイナリを提供していないため、uvはAstralのpython-build-standaloneプロジェクトのディストリビューションを使う」とある
    それはこのGitHubリポジトリ https://github.com/astral-sh/python-build-standalone を指していて、そこではさらに https://gregoryszorc.com/docs/python-build-standalone/main/r... に言及している
    自分の理解が正しければ、Pythonビルド用のソースコードをpython.orgから直接取ってきていないようにも見え、これがどれほど安全なのか確信が持てない
    asdf[2]にも同じ懸念はあるが、asdfはpyenv[3]を使っていて、そちらの方がより公式に近い感じがする
    Pythonのインストールには、uvとasdfのどちらがより良く、より安全なのか、説明できる人はいるだろうか?
    [1] https://docs.astral.sh/uv/guides/install-python/
    [2] https://github.com/asdf-community/asdf-python
    [3] https://github.com/pyenv/pyenv/tree/master/plugins/python-bu...

    • python-build-standaloneはCPythonソースをpython.orgから直接取得している[1]
      そもそも他のどこから取るんだという話だ
      [1]: https://github.com/astral-sh/python-build-standalone/blob/a2...
    • uvcpythonについてはあまり心配していない。プロセスは堅牢で、対応も速く、今では資金もかなりある
      心配なのは、たとえばmdformatのように広く使われているが、主に1人が余暇で保守しているフォーマッタや、何年も更新されておらず、依存ツリーの3段階下にあるような非常に特定の依存関係だ
      活発に開発中のアプリで、すべての更新を固定して手動承認したくはないが、真面目なアプリなら今やそれが必須に見え始めている
      その間に、暗号化されていない.envファイルからAPIキーを取り出しておこう
      大規模なコンシューマー向けWebアプリで被害に遭うのは恥ずかしいが理解はできるとしても、同じホストやシステム上にたまたまある、おもちゃのデモ用リポジトリの間接依存のせいで数百〜数千ドル失うのは痛すぎる
      こういう形でキーを盗まれた場合、OAIやAnthropicは返金してくれるのか知っている人はいる? それともユーザーのミス扱いなのだろうか?
    • そもそもuvは、コンピュータ上で実行してPythonバイナリ、パッケージ、その中のバイナリ、システム全体のツールなどを管理するバイナリ
      Pythonバイナリを彼らがビルドするか、別の誰かがビルドするかで、危険性がどれほど変わるのか分からない
  • 最近の自分のpip installの大半はClaude Codeが提案し、自分はそのままEnterを押しているだけだ
    モデルは数か月前のデータで学習されているのだから、今週何が侵害されたか知るはずがない
    「このパッケージは今安全か」を判断するうえで最悪のフィルタを作ってしまった

    • 怠惰やデューデリジェンス不足をLLMのせいにしてはいけない
    • 何のフィルタのことを言っているんだ?
      Claude Codeにインターネット上のインストール用ソフトウェアを推薦させ、それをそのままインストールしているという話だろう
      Claude CodeやどのLLMであれ、「このパッケージは今安全か」を判断するフィルタだと提案しているのは聞いたことがないし、述べられた理由も含めて、非常に悪いヒューリスティックに見える
    • 古い学習データも一因だが、最新モデルであってもsetup.pyが自分のマシンで何を実行するかは分からない
      実行前にパッケージを実際に検査しているわけではないからだ
      必要なのは、実行前にメタデータを取得して、どんなフックがあるか確認するツールだ
    • Enterを押さなければ簡単に回避できる
    • 「最悪のフィルタ」というのは、Claudeの言う通りにEnterを押すことを指しているのか?
  • Claude Codeはほぼ毎日、ときには1日に何度も更新される
    いつかAnthropicが侵害されたら、私たちは皆ひどい目に遭うだろう

    • 「私たち」って誰のことだ?
    • 権限のないVM/コンテナで、制限されたネットワークアクセスのもとで実行するならそうはならない
      とはいえ、最近は何もかもYOLOだ
    • すでにPolymarketの価格に織り込まれていそうだ
  • GitHubで4月20日に投稿されたこのメッセージを見かけたのだが、少し混乱している
    "deependujha hi @thebaptiste, thanks for inquiring. Release of 2.6.2 is blocked due to some internal reasons. Will notify once release is made."
    もしその時点から問題を把握していたのに今まで警告していなかったのだとしたら、本当に嫌だ
    もっと知っている人が明確に説明してくれるとありがたい
    https://github.com/Lightning-AI/pytorch-lightning/issues/216...

    • LightningのAndyです。悪意あるパッケージは本日UTC 12:45 PMにPyPIへ公開されました
      それ以前に影響を受けた配布物はなく、流出についても把握していませんでした
      GitHub上の元のリリースには問題はありませんでしたが、混乱を防ぐために取り下げています
    • uvを使っている人向け: https://docs.astral.sh/uv/reference/settings/#exclude-newer