要約: 分析の結果、攻撃者は環境に侵入してから15分以内にデータの列挙や取得を始めていることがわかりました。しかも、それを見つけるはずだったツールは機能していませんでした。ここでは、この挙動を確認した3つの典型的な攻撃パターンを取り上げます。
- 盗まれた開発者トークン。汚染されたnpmパッケージや情報窃取マルウェアが、開発者のノートPCからGitHubトークンを盗み出します。攻撃者は後からそのトークンを使い、GitHubからデータを持ち出します。GitHubにはトークンの使われ方を検知するネイティブ機能がなく、企業はコードの流出に対して無防備です。
- AIツールを狙ったClickFixの罠。共有されたClaudeのチャットに、偽のClaude Codeインストールコマンドが載っています。実行するとmacOS向けの情報窃取マルウェアが読み込まれ、ブラウザのCookieやクラウドの認証情報が盗まれます。被害者は他のツールを入れるときと同じようにコマンドを自分で実行するため、エンドポイント検知が作動するとは限りません。
- ヘルプデスクを装ったビッシング。攻撃者はソーシャルエンジニアリングでIT部門になりすまし、本物に似せたサインインページで、従業員に本物のMFAプロンプトを承認させます。IDプロバイダーは攻撃者のログインを正規のものと扱う場合があり、こうした事案の検知には役立ちません。
こうしたインシデントを見つけるには、データと振る舞いに基づく検知が必要です。食い止めるには、自律的な対応が欠かせません。以下では、この両方を取り上げます。
3月、ある開発者がGitHub Desktopをインストールしてサインインし、その日のうちに使うのをやめました。作成されたOAuthトークンは、そのMacのキーチェーンに95日間残ったままでした。6月19日、何者かがこのトークンを使い始めました。
トークンは、欧州の20を超える都市にある住宅用プロキシを経由し、約15秒で76件のリポジトリを取得しました。GitHubはトークンの使われ方を監視していないため、アラートは一切上がりませんでした。一方、Exaforceのプラットフォームは5分以内にこれを検知し、10分以内にトリアージを終えました。
当社のMDRアナリストは情報流出を確認し、検知から数分後に顧客へ通知しました。しかし、何らかの対処が行われた時点で、攻撃者は638件のリポジトリのうち472件からデータを持ち出していました。
この事例は、問題の両面を示しています。異常検知がなければ、トークンが使われていることには誰も気づきませんでした。適切な検知があっても、封じ込めには人間の承認が必要だったため、攻撃者がデータを持ち出すのに十分な時間を与えてしまいました。
開発者のノートPCに眠るトークン
GitHubのセキュリティ機能は、コードやシークレットの検査に重点を置いており、トークンの不正利用は対象外です。 今回のGitHubトークン の侵害は、単一のGitHubセッションに現れた複数の弱いシグナルを重ね合わせることで見つけました。アカウントへのサインインは、これまで確認されたことのないネットワークや都市から行われていました。
このセッションは、macOSしか使ったことのないアカウントで、WindowsのUser-Agentを使い、マシン速度でZIPアーカイブを取得していました。個々のシグナルは、それぞれ説明がつくかもしれません。しかし、すべてが重なれば、悪意ある活動を示していると考えられます。
今回のような、プレフィックスがgho_ のOAuthアプリトークンは期限切れにならず、GitHubが自動で失効させるのは1年後です。当社の検証では、組織のSSOページにはこれらのトークンが一覧表示されすらせず、CLIでしか確認できませんでした。IDプロバイダーで開発者のアカウントを無効にしても、トークンは止まりません。
SCIMがなければ、GitHubは誰かがトークンを失効させるか、ユーザーを組織から削除するまで、トークンを有効なものとして扱い続けます。
AIコーディングツールを使う開発者は、一日中npmパッケージをインストールし、MCPサーバーに接続しています。その大半は、セキュリティチームが監視するパイプラインの外で行われます。Shai-Huludのようなワームは、汚染されたパッケージがインストールされた瞬間に、マシン内のGitHubトークンやクラウドトークンを根こそぎ集めます。
これは何かがコミットされる前に起こります。そのため、リポジトリをスキャンして、侵害されたnpmパッケージの影響を受けたかどうかを調べるだけでは不十分です。
AIツールのインストールを狙うClickFix
macOSのキーチェーンからトークンを盗むには、通常、ログインパスワードをだまし取る情報窃取マルウェアが必要です。
最新のClickFixの罠は、AIツールへの信頼を悪用します。あるインシデントでは、Claude Codeのインストール手順を検索していた従業員が、ワンライナーのインストールコマンドが載った共有Claudeの会話にたどり着きました。
このコマンドはmacOS向けの情報窃取マルウェアを読み込みます(詳細な分析と侵害指標を公開しています)。このマルウェアは「システム環境設定」を装ってパスワードの入力を求め、キーチェーン、ブラウザのCookie、保存済みパスワード、クラウドの認証情報をコピーします。
被害者自身がコマンドを実行するため、メールフィルタリングやダウンロード制御は回避されます。この種の攻撃を見つけるうえで最も有効なのは、エンドポイント検知ソリューションです。影響範囲を評価する際は、そのユーザーが発行したすべてのトークンと認証情報を包括的に分析する必要があります。
偽のIT部門からの電話が、セッション窃取につながる
今年対応したビッシングの事例では、被害者がプッシュ通知を承認してから2.5~7分後に、攻撃者が自身のMFAデバイスを登録し、一括ダウンロードのスクリプトを開始していました。ある事例では、攻撃者が14万件のファイルを持ち出し、流出させたデータと引き換えに身代金を要求しています。
こうした電話の多くは、Scattered Spiderグループがよく使うヘルプデスクのシナリオに沿っています。IT部門を装った電話の主は、URLに社名を含むサインインページへ従業員を誘導します。たとえば、 Microsoftが9月に公開した解説にあるパスキーを装ったcontoso.add-passkey[.]comのようなものです。
このページは、アドバーサリー・イン・ザ・ミドル(AiTM)プロキシを介してログインを中継するか、攻撃者が被害者をデバイスコードによるサインインへと誘導します。
当社が分解したキットの1つは、oskeysetup[.]comでホストされ、一から自作されたものでした。Evilginxなどthe公開キット向けに作られた検知は、こうしたキットには通用しません。
多くの事例で、IDプロバイダーの検知が機能していないことを確認しました。被害者が本物のMFAプロンプトを承認してしまうためです。当社が対応した7月のセッションハイジャックでは、Microsoftは攻撃者の最初のサインインを危険と判定しました。しかし、ユーザーがMFAを通過したことを理由に、そのリスクを「修復済み」に変更しています。数分以内に、盗まれたトークンが別の2か国から1秒以内にリプレイされ、その後のMicrosoftのアラートでようやくユーザーのリスクレベルが引き上げられました。
Exaforceは、OktaとMicrosoftのサインインを結び付け、ユーザーの過去の履歴と照合して検知しました。このアカウントにとって米国からのサインインは初めてで、Linuxデバイスから、これまで使われたことのない家庭用ISP経由でした。こうした事例で最も早い段階の強いシグナルは、多くの場合、ユーザーが一度も使ったことのないデバイスとネットワークからの新しいMFA方式の登録です。
また、攻撃者が同じ企業の複数の従業員を狙い、しかも同じサーバーやドメインを使い回すことが多い点も確認しました。
自律的な対応アクション
ここまで見てきたインシデントに有効な対策は、自律的な対応へ移行することです。対応の自動化自体は決して新しい発想ではありません。ただ、誤った操作によって経営幹部がロックアウトされたり、本番環境の連携が壊れたりすることへの懸念は、常につきまといます。
当社は、アクションを「摩擦」で分類するほうが適していると考えています。つまり、誤った対応をした場合に、認証情報の持ち主がどれだけのコストを負うかという基準です。再サインインや携帯電話の再登録で済むなら、そのアクションは低摩擦であり、確度の高い検知結果をきっかけに実行できます。たとえば、セッションの失効、問題のセッション中に登録されたMFA方式の削除、再び有効化できるキーの無効化がこれに当たります。
パスワードのリセット、アカウントの無効化、恒久的な削除、本番サービスが依存するあらゆる操作には、人間の承認を求めるべきです。承認者は、対象ユーザー本人とその上司でかまいません。サインインが本人のものではないことを、簡単なメッセージで確認してもらいます。
ここで取り上げたアクションの大半はIDや関連する認証情報に関わるものですが、IDプロバイダーだけに限定することはできません。ユーザーのOktaパスワードをリセットしたりOktaセッションを終了したりしても、Microsoft 365、Google Workspace、GitHubがすでに発行したトークンは失効しません。SSO経由で開始されたAWSやSnowflakeのセッションも動き続けます。
ビッシングの事例では、ユーザーのIdPセッションを失効させた後も、44分から3時間にわたってデータの持ち出しが続いていました。ある事例では、パスワードをリセットした後も攻撃者のメールボックスルールが残っていました。OktaのUniversal LogoutはGoogle WorkspaceやSlackなど一部のアプリには届きますが、GitHub、Snowflake、AIモデルプロバイダーには届きません。
各アプリケーションの失効アクションは、それを実行するアカウントと併せて、事前に整備しておくのが最善です。必要な権限が誰にも付与されておらず、インシデントの最中に対応アクションが403で失敗するのを目にしたこともあります。
すべてのデータソースについてこうした対応を構築するのは、気が遠くなる作業かもしれません。まずは、最も重要なデータを保持するサービスから始めることをお勧めします。
- 生産性: Google Workspace、Office 365、Box、Dropbox、Slack
- クラウド: AWS、GCP、Azure
- AIサービス: Anthropic、OpenAI
- データ: Snowflake、Databricks
- コード: GitHub、GitLab
最初に取り入れたい低摩擦の対応と、その実装方法は次のとおりです。
OKTA
アクション: セッションと、Oktaが発行したOAuthトークンを失効させる
API: DELETE /api/v1/users/{id}/sessions?oauthTokens=true
必要な権限: okta.users.readおよびokta.users.manageスコープ。加えて、okta.users.readとokta.users.lifecycle.clearSessionsだけを持つカスタム管理者ロール
アクション: 攻撃者が登録したものを含め、ユーザーのすべての認証要素をリセットする
API: POST /api/v1/users/{id}/lifecycle/reset_factors
必要な権限: 同じスコープ。ロールにはokta.users.credentials.resetFactorsを追加
Microsoft Entra ID
アクション: リフレッシュトークンとセッションCookieを失効させる
API: POST /users/{id}/revokeSignInSessions
必要な権限: User.RevokeSessions.All。ユーザーの検索にはUser.Read.Allも必要
アクション: 攻撃者が登録したものを含め、ユーザーのMFA方式を削除する
API: DELETE /users/{id}/authentication/{type}Methods/{methodId}(電話、Authenticatorアプリ、ソフトウェアOATH、FIDO2、Windows Hello、一時アクセスパスの各方式に対して実行)
必要な権限: UserAuthenticationMethod.ReadWrite.AllおよびUser.Read.All
Google Workspace
アクション: ウェブセッションとデバイスセッションを終了し、アプリのOAuthトークンを失効させる
API: POST /admin/directory/v1/users/{userKey}/signOut、DELETE /admin/directory/v1/users/{userKey}/tokens/{clientId}
必要な権限: admin.directory.user.securityスコープ。加えて、委任された管理者ロール
GitHub Enterprise Cloud(組織レベルのSAML SSO)
アクション: 盗まれたトークンを組織から削除する
API: GET /orgs/{org}/credential-authorizations?login= {user}で該当トークンを探し、DELETE /orgs/{org}/credentialauthorizations/{credential_id}で削除する
必要な権限: admin:orgを持つ組織オーナー、または組織のAdministration(書き込み)権限を持つGitHub App。これより絞った権限はありません
Snowflake
アクション: プログラムによるアクセストークンを無効化する
API: 独自のSQL(例: ALTER USER {name} MODIFY PAT {token} SET DISABLED TRUE)をSQL API(POST /api/v2/statements)経由で送信する
必要な権限: 対象ユーザーに対するMODIFY PROGRAMMATIC AUTHENTICATION METHODS権限を持つロールが割り当てられた、専用のサービスユーザー
AWS
アクション: IAMユーザーにすでに発行されたSTSセッションを終了する
API: PutUserPolicy(現時点より前に発行されたセッション(aws:TokenIssueTime)を拒否するインラインポリシーを設定)
必要な権限: iam:PutUserPolicy。加えて、iam:GetUserとiam:GetUserPolicy
Anthropic
アクション: APIキーを無効化する
API: POST /v1/organizations/api_keys/{id}({“status”:”inactive”}を指定)
必要な権限: Admin APIキー
Exaforceはこれらの攻撃にどう対処したか
Exaforceは、オプションのMDRサービスを備えたエージェント型SOCプラットフォームです。当社のエージェント(Exabots)が、検知エンジニアリング、アラートのトリアージ、調査、脅威ハンティング、対応を担当します。エージェントは統合データプラットフォーム上で動作し、SIEMとして使うことも、既存のSIEMと併用することもできます。
このプラットフォームには800種類のAI/ML異常検知が組み込まれており、重要なクラウド、SaaS、ID、エンドポイント、AIサービスにわたって、ここで紹介したようなインシデントの検知を支援します。エージェントが実行できる動的な対応アクションは100以上あります。重要なサービスごとに自分で構築・保守する必要はありません。