GitHubで発見された感染済みリポジトリが10万件超
(apiiro.com)- 2023年半ばに始まった**リポジトリ混同(repo confusion)**キャンペーンが再拡大し、GitHubで類似の悪意あるペイロードを含むリポジトリが10万件以上検出された
- 攻撃者は正規リポジトリに似た悪意ある複製を作って開発者の誤認を誘い、複製・ローダー挿入・再アップロード・大量フォーク・ひそかな宣伝を組み合わせている
- 悪意あるリポジトリを実行すると、7段階の難読化の後にPythonコードとバイナリがダウンロードされ、ログイン情報・ブラウザのパスワード・Cookieなどの機密データが窃取される
- GitHubが大半のフォークを自動削除しても、検知を逃れたリポジトリや手動アップロード版は残り、全体の1%だけが生き残っても数千件の悪性リポジトリが維持される
- 攻撃の流れがPyPIの悪性パッケージからGitHubリポジトリへ移ることで、パッケージマネージャ外のソフトウェアサプライチェーンも直接の攻撃面になっている
リポジトリ混同攻撃の手法
- リポジトリ混同は、ユーザーが正規リポジトリではなく悪意あるリポジトリをダウンロードするよう誘導する点でdependency confusionに似ている
- 違いは悪用ポイントにある
- dependency confusionはパッケージマネージャの動作方式を利用する
- リポジトリ混同は、人が見た目の似たリポジトリを誤って選ぶ状況に依存する
- 今回のキャンペーンは、GitHubに悪性リポジトリを大量拡散して感染可能性を高めている
TwitterFollowBot,WhatsappBOT,discord-boost-tool,Twitch-Follow-Botなど既存リポジトリを複製する- 複製版にマルウェアローダーを挿入する
- 同じ名前でGitHubに再アップロードする
- 各リポジトリを自動で数千回フォークする
- フォーラムやDiscordなどでひそかに宣伝する
悪意あるリポジトリ実行後の流れ
- ユーザーが悪意あるリポジトリを使うと、隠されたペイロードが7段階の難読化を解除する
- その後、悪意あるPythonコードとバイナリ実行ファイルを取得する
- 悪性コードは主にBlackCap-Grabberの改変版に基づいている
- 収集対象は、複数アプリのログイン資格情報、ブラウザのパスワードとCookie、その他の機密データである
- 窃取されたデータは攻撃者のC&C(command-and-control)サーバーへ送信され、追加の悪性活動が続く
- 関連コードの分析はTrend Microのtechnical analysisで確認できる
GitHubの自動削除と残るリポジトリ
- GitHubは自動化を識別し、フォークされたリポジトリの大半をすばやく削除している
- ただし、自動化検知は多くのリポジトリを見逃しており、手動でアップロードされたリポジトリは生き残る
- 攻撃チェーンは大規模に自動化されているため、1%しか残らなくても数千件の悪性リポジトリになる
- GitHubで
🔥 2024 language:pythonを検索すると、現在拡散中の一部リポジトリを確認できる - 削除済みリポジトリまで含めると、全体規模は数百万件に達する
- 削除は通常アップロードから数時間後に起こるため、記録化が難しい
- 元のリポジトリの多くは残っており、削除は主にfork bombを狙ったものだ
- 例として、Mattia69のリポジトリ一覧では要約欄に数千のフォークが見えるが、フォーク詳細には表示されない
- 一部ユーザーが悪意あるリポジトリと知らずにフォークすることで、二次的なソーシャルエンジニアリングのネットワーク効果も生じている
キャンペーンの展開時期
- 2023年5月: PhylumがPyPIに公開された悪性パッケージを報告
- これらのパッケージは現在のペイロードの初期部分を含んでいた
chatgpt-apiのような人気GitHubリポジトリのフォークに仕込まれたos.system("pip install package")呼び出しによって拡散した
- 2023年7〜8月: 複数の悪性リポジトリがGitHubに公開され、PyPIパッケージを取得する代わりにペイロードを直接配布するようになった
- これはPyPIが悪性パッケージを削除し、セキュリティコミュニティの関心が高まった後の変化である
- Trend MicroのAliakbar ZahraviとPeter Girnusが技術分析を公開した
- 2023年11月〜現在: 類似の悪意あるペイロードを含むリポジトリが10万件以上検出され、その数は増え続けている
- この手法が攻撃者に有利な理由は明確だ
- GitHubは規模が大きいため、大量のインスタンスでも相対的には小さく、検出しにくい
- 以前と違ってパッケージマネージャが介在しないため、明示的な悪性パッケージ名が指標として残らない
- 対象リポジトリが小規模なニッチ領域で人気も低く、開発者が悪性ななりすましリポジトリを誤ってクローンしやすい
パッケージマネージャからSCMへの移行
- PyPIの悪性パッケージからGitHubの悪性リポジトリへの移行は、複数のパッケージマネージャやSCMプラットフォームで観測されてきた流れと一致している
- セキュリティコミュニティがパッケージマネージャにより注力するようになった結果、攻撃経路が別の場所へ移った形だ
- GitHubや類似プラットフォームは、アカウントやリポジトリを自動生成しやすく、便利なAPIと回避しやすい緩いrate limitを提供している
- 無数のリポジトリの間に紛れ込めるため、SCMはソフトウェアサプライチェーンをひそかに感染させるのに適した標的になっている
- dependency confusionキャンペーン、パッケージレジストリ上の悪性コード、SCM経由の悪性コード拡散は、ツールやセキュリティメカニズムが多くてもソフトウェアサプライチェーンセキュリティが脆弱であることを示している
感染有無を確認する指標
- Pythonコードで次のパターンを検索し、一致項目を調査すべきだ
exec(Fernetexec(requestsexec(__importexec(bytesexec("""\nimportexec(compile__import__("builtins").exec(
- ソーシャルプラットフォーム自動化、ボット、ゲーム関連のリポジトリがローカルにないか確認し、削除する必要がある
- どうしても使う必要があるなら再インストールするが、出所を慎重に検証するか、サンドボックスで実行すべきだ
- この種のリポジトリをクローンした可能性があるなら、以下のCookie、資格情報、鍵が窃取されたものとして対応すべきだ
- ブラウザ: 金融サービス、メールサービス、暗号資産サービス、Amazon、eBay、AliExpress、Facebook、Instagram、Twitter、Youtube、Discord、TikTok、Telegram、Twitch、Steam、Yahoo、ExpressVPN、Spotify、ストリーミングサービス
- アプリ: Exodus、Atomic Wallet、Guarda、Coinomi、Ethereum
- ファイルチェックサムの完全な一覧は実用上扱いにくいが、一部の共通項目はVirusTotal graphで確認できる
- Cloudflareは通知を受けた後、発見された悪性アドレスのDNSレコードを無効化した
防御と対応
- GitHubは通知を受けて悪性リポジトリの大半を削除したが、キャンペーンは続いている
- サプライチェーンに悪性コードを注入しようとする攻撃は、ますます広がっている
- システム・ネットワークレベルでマルウェアを検出するソリューションは多いが、サプライチェーンは攻撃者にとって依然として大きく収益性の高い攻撃面だ
- 悪性リポジトリを発見したら、このキャンペーンの一部かどうかに関係なく、GitHubのabuse or spam reportから報告できる
- Apiiroは、接続されたコードベースを監視するマルウェア検出システムを構築している
- LLMベースのコード分析
- 実行フロー全体グラフへのコード分解
- ヒューリスティックエンジン
- 動的デコード、復号、難読化解除
- 注入された悪性ペイロードを監視しなければ、組織のセキュリティは、開発者がほぼ同一の誤ったリポジトリを選ばない能力、CI/CD設定ミスが一切ない状態、100%安全なサードパーティコードといった条件に依存することになる
- 一般的な脆弱性の検知と収集を超えて、次世代のソフトウェアサプライチェーンおよびアプリケーションリスクを可視化するアプローチが必要だ
1件のコメント
Hacker Newsのコメント
公開リポジトリや外部ソースから取り込むコードには注意し、依存関係ツリーの検証を行うべきだという一般的な警告を超えて、公開リポジトリに悪意あるコードが大量にあるなら、その内容で学習したLLMや自動化ツールにどんな影響があるのか気になる
Copilotのようなツールが長いコード回答を生成する際、悪意ある部分が偶然混ざり込む可能性もありそう
単純なインジェクション脆弱性のようなものは、すでに頻繁に目撃されている
今はそうでないとしても、数年以内には十分あり得そう
AIは正確性について何の保証もしてくれない
攻撃者がHugging Face Safetensors変換スペースに接続されたサービスボットを掌握できることを示したもので、これはエコシステム内の安全でない機械学習モデルをより安全なバージョンに変換する人気サービス
LLMを使うならコードレビューにもっと労力を投じる必要があり、そのトレードオフには価値があると思う
ただし実際の事故につながるには、主に2つの壁がある: 生成器がそうしたコードを避けるよう内部指示を受けていること、そしてLLMの特性上、実際の攻撃者のアドレスをそのまま繰り返す可能性は低いこと
それでもバインドシェル、サービス拒否、現場からの情報流出のようなさまざまな攻撃ベクトルは依然として残る
GitHubはUsenetが失敗したのと似た形で失敗しつつある
誰でもリポジトリを作成でき、公式リポジトリとスパムリポジトリを区別してくれるものがない
Amazonが「すべてのものの店」を目指した結果、「すべてのものの90%はゴミ」にぶつかって大半がゴミの店になったように、GitHubも自分たちの製品が「すべての人のためのリポジトリ」なのか「信頼できるコード」なのかを決めるべき
例えば公式のPG JDBCでさえ、スパマーが再現できない要素がないように見えるが、これが感染リポジトリではないとどう信頼できるのか: https://github.com/pgjdbc
Sonatypeは
groupIdに使われている逆引きドメインの所有権証明を求めており、この場合はorg.postgresql方法はこちら: https://central.sonatype.org/faq/how-to-set-txt-record/
さらに安心したいなら、Maven Centralに公開されるすべての成果物は署名されているためGPG署名も確認できるが、Postgresが署名に使う鍵をSonatypeとは独立した経路で入手する必要があるという欠点がある
PGの場合、軽く検索しても鍵は見つからなかった
GitHubには約5億個のリポジトリがあるので、この程度なら実際にはかなり良いほう
感染リポジトリを使ってしまうような開発者なら、GitHubにそうしたリポジトリがなくても、安全でない製品を作る別の方法はいくらでも見つけるはず
例に挙げられた組織は、単にそれをしていないだけのように見える
サプライチェーン問題は本当に厄介
npm リリースを直接ターゲットにしているわけではないが、BrowserBox という軽量な仮想化 Web ブラウザプロジェクトを監視するために npm リリースを作り、socket.dev を使っている
このプロジェクトもサブ依存関係全体で約800個、トップレベルの依存関係は19個だけ使っているが、スタック全体で見ると比較的軽い部類
いまは800個の依存関係をすべて npm の
@browserbox名前空間にスナップショットしておき、見つかった脆弱性を追跡してパッチするべきか悩んでいる正気ではないように聞こえるが、現状がそうで、少なくともそうすれば Node/JS 側のサプライチェーン脆弱性は会社のセキュリティレベルの範囲内で自分たちで保証できる
https://socket.dev
https://github.com/BrowserBox/BrowserBox
ロックファイルがツリー全体の sha256 を保持しているので、リポジトリがハッキングされても、改ざん防止のためにミラーリングする必要はない
最新より数か月遅れのバージョンに固定するのが、新しい CVE を避けつつ、古すぎるバージョンに縛られて後で一気に大きく直す状況も避けられる、適切なバランスに見える
ダウンロード数は、似た目的のトップレベル依存関係と比べるなら悪くない指標のように思うが、主観的な判断ではある
Austral は線形型によって依存関係に細かい権限を与える
グラフィックライブラリにファイル入出力は不要だし、ネットワーク転送ライブラリにマイクへのアクセスは不要、という具合
あくまで緩和策だが、ほかの言語でも見てみたい
10年ほど前に .NET から Java に移った後、依存関係地獄に費やす時間が大きく増えて驚いたし、最近では Java と Python のプロジェクトのどちらでも、脆弱性対応の更新や依存関係の問題にかかる時間が恐ろしく多い
.NET でこの問題が少なかった理由は、自動パッケージ管理の導入が比較的遅く、NuGet も若い部類だったため、当時は多くのプロジェクトがまだ採用しておらず、巨大な推移的依存関係ツリーを避ける文化が強かったからだと思う
Boeing の最近の問題も似て見える
過去数十年にわたり生産を外部サプライヤーへより多く移し、コスト最適化に集中する中でサプライチェーン管理がますます難しくなっており、大きな視点では現代のソフトウェア工学におけるサプライチェーン文化に似ている
サプライチェーンセキュリティのためにパッケージマネージャを禁止していた金融機関で働いていたときが、依存関係管理の面倒が最も少なく、品質問題も最も少なかった
明示的に変えない限り絶対に変わらないコードには利点がある
他人ならパッケージを持ってくる部分も自分たちでかなり実装したが、必要なことだけを行い、より高いコード基準を適用したので、理解・デバッグ・修正がしやすかった
最初に書くコストは一度きりでうまく償却されるが、すべての人のためにすべてをやろうとするコードを扱う反復コストは、長期的にはより大きくなり、たいてい蓄積していく
Rich Hickey の「Simple Made Easy」はこの現象をよく示しており、シンプルなことと簡単なことは違い、シンプルな選択肢は初期にはより難しく見えても、二次的な効果が積み重なると長期的にはより簡単になる
似たようなリポジトリを偶然見かけて、こういうものにはすでに気づいていた
もともと適当なリポジトリのコードを実行することはなかったが、今ではリポジトリと所有者を信頼していても サンドボックス VM を立ち上げる
今日の開発者なら、仕事、趣味、個人用を少なくとも3つの環境にしっかり分けるべきだと思う
悪意はなくても、設計がずさんだったり愚かに書かれていたりするプロジェクトがある
少し前に実行したプログラムは、私が何か作業を依頼する前に
~/.bashrcに3行追加しており、数日後になってようやく気づいたどんな開発者がこれを良い考えだと思うのか理解できず、それ以来、外部コードを実行するたびにサンドボックスを使うようになった
私の日常用 OS だ
こんなことを許す雇用主が実際にいるのか?
職場でこうした問題を避けるためにどんなツールを使っているのか、現在の構成に満足しているのか気になる
かなり小さなチームで週間ダウンロード数の多いSDKを開発しており、snyk、aikido.dev、renovateベースのソリューションなどを評価してみたが、こうした問題に役立つのかははっきりしない
まだ小さなチームなので、snykのように誤検知が多いツールを扱うのも負担になる
Sonatypeがすべてのパッケージを解析して各種メタデータを付与し、Firewallで使えるポリシーを定義して残りをフィルタリングする
公開依存関係にしか効かないが、数年使ってみた結果、かなりうまく機能している
これまでマルウェアの問題はなく、既知の脆弱性があるパッケージはコードベースに入ってこられず、使用中のものに脆弱性が見つかれば通知を受け取る
見つかったサプライチェーン脆弱性を到達可能、到達不能、未確定に分けてくれるので分類がずっと楽になり、新しい脆弱性を評価する時間が大幅に減った
言及されているベンダーは悪意あるコードを検出するのではなく、脆弱性だけを検出する
脆弱性検出に優れていても、コードベースに仕込まれた悪意あるコードからは依然として守られない
静的・動的・メタデータ解析を行い、シェル実行、SSHキーの使用、ネットワーク通信、decode+evalの使用など40以上の属性を検査して危険なパッケージを表示する
https://github.com/ossillate-inc/packj
これまではかなりうまく動いている
https://trivy.dev/
curlでシェルのインストールスクリプトを取得してsudoで実行する慣行は、そろそろ終わるのだろうか「当社のソフトウェアをインストールするには、
curl [https://somesite/install.sh](<https://somesite/install.sh>)' | sudo shを実行してください」のような方式は、記事で言及されている感染コードと非常に相性がよさそうだ私たちのシステムは、言及されたパターンを毎週約100件列挙しており、そのうち約3%が悪意あるものだ
この慣行が終わるのを見たい
npm iも同じ権限を持つ現在一般的な依存関係ダウンロードツールの中で、インストール時やビルド時に敵対的なコードが実行されないものは、
go getくらいしか知らない少なくとも爆発を区画化するには、サンドボックス内で作業するためのより良いツールが必要だ
ChromeOSの「仮想マシンがメインデスクトップにWaylandウィンドウを開ける」方式はすっきりしているが、最後に見たとき、そのコードはあまりきれいでも再利用可能でもなかった
その目的のために予約されたドメインだ: https://www.rfc-editor.org/rfc/rfc2606.html#section-3
.deb/.rpm/インストーラをダウンロードしてください」、あるいは最悪の場合の「発行者ではなく第三者がパッケージングしたものを信頼してください」と比べて、特に悪いわけではないnpmでは
--ignore-scriptsでマルウェア実行を緩和できるhttps://blog.uirig.com/getting-rid-of-npm-scripts
運がよければCIで異常な挙動をして捕まえられるかもしれない
本当の解決策はhttps://github.com/crev-dev/cargo-crevのような評判システムだが、残念ながらほとんど使われていない
Makefileが必要だというコメントにも注目すべきだ
こうした報告が相次いでいるので、この数か月、開発環境のセキュリティを少しずつ改善している
VSCode の dev containers を開発に使っている: https://code.visualstudio.com/docs/devcontainers/create-dev-...
一度作っておけば Docker の知識がそれほどなくても使いやすく、Web/コンソールアプリを立ち上げるにはよいが、Flutter や Electron のようなものは難しかった
小さなプロジェクトでは GitHub Codespaces にも慣れてきた: https://github.com/codespaces
以前、面接で簡単な Node プロジェクトを修正するライブコーディングをしたことがあるが、今ならそういう状況ではコンテナや Codespaces を必ず使うと思う: https://www.welivesecurity.com/en/eset-research/lazarus-luri...
npm、Node、Docker のベストプラクティスについては OWASP のガイドラインを定期的に読み、Docker ではできるだけ小さいイメージと明示的なイメージタグを使う、といった形で適用している: https://cheatsheetseries.owasp.org/cheatsheets/NodeJS_Docker...
npm/python パッケージはインストール前に socket.dev で環境変数へのアクセス、ネットワーク呼び出し、サプライチェーン攻撃、最近のコード所有権の変更などを確認し、OWASP が推奨するように postinstall スクリプトをグローバルに無効化することもできる: https://cheatsheetseries.owasp.org/cheatsheets/NPM_Security_...
1年もたっていない事例として、トロイの木馬ウイルス入りのリポジトリがあった: https://github.com/orgs/community/discussions/63603
リポジトリが主張した通りに動作しただけだ
公式リポジトリであることを単に表示するだけでも、ある程度の注目を集められる
いったい何が起きるというのか /s
それでも、GitHub はどのリポジトリがプロジェクトの公式リポジトリなのかをもっと分かりやすく示すべきだ、という点には同意する