AAD GraphアクティビティログがElasticに取り込まれ、 SIEM/XDRソリューション内での脅威検出に使用できるようになりました。その文章は本来なら刺激的なものではないはずなのに、実際は刺激的なのだ。過去10年間の大半において、このテレメトリデータは顧客がアクセスできるログストリームとして存在していなかった。Microsoft Graphアクティビティログ(最新のgraph.microsoft.comのインターフェース)は、2024年4月に一般提供開始されました。攻撃ツールが実際に攻撃する唯一の対象である、従来のgraph.windows.netのインターフェースは、2026年初頭まで公開されなかった。
この記事では、ループ全体を最初から最後まで解説します。可視性が重要な理由、ログをElasticに取り込む方法、手動およびROADreconを使用して現実的な偵察を生成する方法、そしてES|QLで結果を調査する方法。以下の内容はすべて、実際のテナントに対して検証済みです。
重要なポイント
-
AAD Graph アクティビティ ログは、 Azure 統合を介して Elastic に取り込まれ、完全な ECS 抽出とともに
logs-azure.aadgraphactivitylogs-*に格納されます。 -
ROADtools、AADInternals、および関連ツールは、長年にわたり可視性のギャップの中で運用されてきた。ディフェンダーはコールを録音していなかった。
-
AAD Graph は「非推奨」となっていますが、ほとんどのテナントでは引き続きクエリを実行できます。内部APIバージョン1.61では、Microsoft Graphでは返されないデータが依然として返されます。
-
ECSフィールドの土地タイプ(
event.action、event.outcome、http.request.method、source.ip、user.id、user_agent.original)。データセットの追加データはazure.aadgraphactivitylogs.properties.*の下でクエリ可能です。 -
以下の5つのハンティングで確実にアクティビティを検出できます。ツールユーザーエージェント、エンドポイントの広範性、
*-internalAPIの不正使用、FOCIクライアントIDの不一致、および4xxエラーの急増。
防御側の可視性の短い歴史
防御側は、サインイン、条件付きアクセス、役割割り当て、OAuth同意付与などに何年も費やしてきた。攻撃ツールが実際に攻撃する基盤となるディレクトリAPIについて解説しているコンテンツは非常に少ない。理由は構造的なものだ。これらのAPIに関して、顧客がアクセスできるログが存在しなかったのだ。Microsoft Graph Activity Logsが最初にリリースされました(プレビュー版は2023年10月、一般提供開始は2024年4月)。AzureADGraphActivityLogsは、2026年初頭にようやく登場しました。
過去10年間のほとんどの期間、AADグラフの列挙はSOC(セキュリティオペレーションセンター)からは見えなかった。それはテレメトリが隠されていたからではなく、そもそも存在していなかったからだ。ROADtools、AADInternals、MSOLSpray、Microburst。それらのどれも、たとえ完璧なログ設定を行ったとしても、誰かが取得できるようなデータを生成しなかった。
AzureADGraphActivityLogsがプラットフォームログインデックスに記録され始めると、状況は一変します。
AADグラフは「非推奨」とされていますが、依然として活発に利用されています。
簡単な復習です。Azure AD Graph は、Entra ID ディレクトリ オブジェクト用の従来の REST API であり、 https://graph.windows.net/{tenantId}/{objecttype}でホストされ、API バージョンは 1.5、1.6、1.61 - internalなどです。マイクロソフトは2019年から皆にMicrosoft Graphへの移行を促してきたが、そのサポート終了日は何度か延期されている。
非推奨機能はなくなっていません。2026年においても、AAD Graphは、従来のアクセスパスが引き続き利用可能な環境、またはアプリケーションによるAAD Graphの使用が明示的にブロックされていない環境において、リクエストに応答することができます。攻撃の標的として残り続ける理由をいくつか挙げます。
-
攻撃者側のツールは移植されていません。ROADrecon は今でも
gatherにそれを使用しています。AADInternalsには、それをラップする数十個のコマンドレットがあります。 -
*-internalAPIバージョンはより多くのデータを返します。1.61-internal、通常のディレクトリウォーク中にユーザーオブジェクト上でstrongAuthenticationDetailインラインで公開します。Microsoft Graph の同等の機能は、UserAuthenticationMethod.Read.Allによってゲートされる別の /authentication/methods エンドポイントの背後にあります。その非対称性こそ、一括列挙ツールが悪用する点である。 -
このブロックは単一の切り替えボタンではありません。
blockAzureADGraphAccessコントロールはapplication.authenticationBehaviors上でアプリごとに存在するため、テナント全体でブロックするには、すべてのアプリ登録を反復処理する必要があります。ほとんどの環境ではそうしていません。なぜなら、一部のレガシー自動化システムは依然としてAPIに依存しているからです。マイクロソフトの段階的なサポート終了措置は、マイクロソフトのスケジュールに基づいて実施され、防御側のスケジュールには従わない。 -
可視性が存在しなかったため、レッドチームや攻撃者は関連情報を得るためにAPIエンドポイントを集中攻撃することができた。
正当なAAD Graphトラフィックの大部分は、少数のマイクロソフト社製ファーストパーティ呼び出し元によって占められている。テストテナントでは、ボリューム順でMicrosoft.OData.Client 、 Microsoft Azure Graph Client Library 、ファーストパーティAppIdからの空のUAテール、 Microsoft ADO.NET Data Services 、Azureポータル(ポータルアプリIDに対するChrome UA)の順でした。その認識可能な範囲外にあるものは、内部ツールか不正な活動のいずれかである。これは、優れた脅威ハンティング/検出データセットとなる。もしあなたがそれを撮影しているなら。
取り込みパイプラインの設定
既にElastic Azureとの統合を実行し、診断設定をイベントハブに転送している場合は、このセクションをざっと読んでください。おそらく、ログカテゴリを1つ追加で有効にするだけで済むでしょう。ゼロから始めると、約20分ほどの道のりです。
ステップ1:ログを受信するスタック
Elasticのデプロイメントであればどれでも動作します。Elastic Cloudのトライアルは、プロトタイピングにおいて最も手間のかからない選択肢です。別の選択肢としては、 Elastic Container Project を利用する方法もあります。Azureとの連携は、有効化されると既にAzureADGraphActivityLogsを処理します。
ステップ2:Azureとの統合を追加する
Kibanaで、[統合] > [Azure Logs] > [Azure Logsを追加]を選択します。テナントと同じサブスクリプション内のイベントハブに、イベントハブの接続文字列、イベントハブ名、およびオフセットチェックポイント用のストレージアカウントをすべて入力してください。
Azure Logs v2 データストリームを具体的に有効にしてください。これがAADグラフアクティビティログの入り口です。イベントルーターはcategory == "AzureADGraphActivityLogs"に一致し、ドキュメントをlogs-azure.aadgraphactivitylogs-*にリダイレクトします。では、データセットパイプラインが完全なECS抽出を実行します。
Azure AD Graph Activity Logs を独立した統合アイテムとして分離しましたので、「Azure AD Graph Activity Logs」で検索し、ポリシーテンプレートから直接インストールできます。
ステップ3:Entra IDで診断設定を有効にする
これは、ほとんどのディフェンダーが見落としているステップだ。AzureADGraphActivityLogs は、診断設定カテゴリとして比較的新しいものです。Entra IDの診断設定が既にしばらく前から構成されている場合でも、新しいカテゴリには改めてチェックを入れる必要があります。そうでなければ、データはマイクロソフトのテナント境界内で生成され、そこで消滅する。
Azure ポータルで:
- Entra ID > モニタリング > 診断設定 > + 診断設定を追加。
- 名前を言ってください。
- 「ログ」の下にある「AzureADGraphActivityLogs」を確認してください。ついでに、MicrosoftGraphActivityLogs、SignInLogs、AuditLogs がまだ有効になっていない場合は、有効にしておくと良いでしょう。この統合機能はそれらすべてに対応します。
- 「宛先の詳細」で、「イベントハブにストリーミング」(手順2と同じもの)を選択します。
- 保存。
ステップ4:データが正しく流れていることを確認する
数分以内に、イベントが発生し始めるはずです。最速の健全性チェック:
FROM logs-azure.aadgraphactivitylogs-*
| LIMIT 20
ドキュメントにevent.action 、 http.request.method 、 zure.aadgraphactivitylogs.properties.*フィールドがすべて入力されていれば問題ありません。何も表示されない場合は、イベントハブのアクセス許可を忘れている、接続文字列にタイプミスがある、またはAAD Graphカテゴリにチェックが入っていない、といったことが考えられます。
いくつかのイベントを強制的に発生させるには、Azureポータルにサインインし、「ユーザー」または「アプリケーション」の周辺をクリックします。ポータルは、一部のオブジェクトの詳細情報を取得するために、内部的に引き続きAAD Graphを呼び出します。それでも何も生成されない場合は、このcurlループが実行されます。
TOKEN=$(az account get-access-token --resource https://graph.windows.net --query accessToken -o tsv)
TID=$(az account show --query tenantId -o tsv)
for obj in users groups servicePrincipals applications tenantDetails; do
curl -sS -o /dev/null -H "Authorization: Bearer $TOKEN" \
"https://graph.windows.net/$TID/$obj?api-version=1.6&\$top=5"
done
フィールド形状
データが流れ始めると、プロパティは型付きの最上位フィールドとして配置されます。狩猟において重要なもの:
- ECS 、直接入力されたもの:
event.action(メソッド + コレクションから派生した意味動詞、例:users-read, batch-execute)、event.outcome、event.duration、http.request.method、http.response.status_code, source.ip、およびsource.geo.*, user.id, user_agent.original(解析されたサブフィールドを含む)、url.path, azure.tenant_id, cloud.service.name = "Azure AD Graph"。 - データセット固有の項目は
zure.aadgraphactivitylogs.properties.*: app_id,、app_id、api_version、actor_type、roles、scopes、wids、identity_provider、client_auth_method、sign_in_activity_id、token_issued_atです。 related.useruser.idとproperties.app_idの両方を取得するため、OAuthクライアント次元のピボットはユーザーピボットと並行して機能します。
フォレンジック調査のために、生のJSONデータはevent.originalに保存されます。通常の狩猟では、そこに手を伸ばす必要はないはずです。そうするなら、ES|QLのJSON_EXTRACT()がその手段となる。
ROADreconによるAADグラフ列挙
何を狩るべきかを知るには、その活動がどのようなものかを知る必要がある。以下の2つのツールキットは、レッドチームやセキュリティ研究のワークフローにおいて、AAD Graphトラフィックの最も一般的な発生源です。私は両方のテスト用テナントに対して実行しました。
注:このコードの誤用については一切責任を負いません。これらのツールは、ご自身が所有するテナント、またはテストを行うための明確な書面による許可を得ているテナントに対してのみ実行してください。
ROADrecon: 一括列挙テスト
ROADreconは、Dirk-jan Mollema氏が開発したEntra ID研究フレームワークであるROADtoolsのデータ収集モジュールです。まだ使ったことがないなら、ぜひ使ってみることを強くお勧めします。gather は、ディレクトリ内のすべての興味深いオブジェクト タイプ (ユーザー、グループ、サービス プリンシパル、アプリケーション、デバイス、ディレクトリ ロール、ロール割り当て、適格なロール割り当て、OAuth2 アクセス許可、管理単位) を走査し、結果を SQLite に書き込みます。
セットアップは標準的なワークフローです。
pip install roadrecon
roadrecon auth --device-code -c 04b07795-8ddb-461a-bbee-02f9e1bf7b46 -r https://graph.windows.net
デバイスコードフローでは、URLとコードが提供されます。弊社では、デフォルトとして Microsoft Azure CLI ( 1b730954-1685-4b74-9bfd-dac224a7b894 - AAD PowerShell) を使用していますが、弊社のテナントでは 403 エラーが返されました。ログイン後:
roadrecon gather
roadrecon gatherを実行し、結果として得られたトークンが正常に完了しました。テナントの視点から見ると、この実行では約 1 分で約2,000件を超えるAAD Graph呼び出しとログが生成されました。ROADreconが認識するあらゆるオブジェクトタイプを一括列挙します。
このことから、これらの異常を早期に発見するための初期的な検出方法をいくつか構築することができます。
AAD Graphの脅威検出における重要なフィールド
探索を開始する前に、異常を検出するための確実な出発点となる分野をいくつか紹介します。
| フィールド | 説明 | 見つけることができるもの |
|---|---|---|
event.action | 意味動詞(HTTPメソッド+コレクション、例:`users-read`、`batch-execute`) | 意図に基づいてAADグラフのアクティビティを分離する安価なフィルター |
http.request.method | GET、POST、PATCH、DELETE | 読み取り(偵察)と書き込み(変更、認証情報注入、永続化) |
http.response.status_code | HTTPステータスが返されました | 偵察が成功したか、ブロックされたか。4xxの連発は、権限の調査またはブルートフォース攻撃を示している。 |
user.id | 呼び出し元のユーザーのディレクトリオブジェクトID | ユーザーの識別情報を特定し、SignInLogs/AuditLogs 内のそのユーザーの他のアクティビティに焦点を移します。 |
user_agent.original | 呼び出し元の完全なUA文字列 | 呼び出し元がマイクロソフトの公式ライブラリ、開発者ツール(curl、Python aiohttp)、または既知の攻撃ツールであるかどうか |
url.path | リソースパス(/users、/policies、/servicePrincipals、...) | どのディレクトリオブジェクトタイプが操作されているか。異なるパスにわたる範囲は一括列挙を示します。 |
azure.aadgraphactivitylogs.properties.app_id | トークンを発行したOAuthクライアントID | トラフィックが正当なファーストパーティクライアントから来ているのか、FOCIスワップ型の不正利用経路から来ているのかに関わらず |
azure.aadgraphactivitylogs.properties.api_version | 1.5、1.6、1.61-内部など | 呼び出し元が、攻撃ツールが特に標的とする内部専用フィールド(strongAuthenticationDetail、完全なCAPセット)を要求しているかどうか |
azure.aadgraphactivitylogs.properties.actor_type | ユーザー、アプリケーション、サービスプリンシパル | 人間による呼び出し vs サービスプリンシパル/アプリ専用フロー |
azure.aadgraphactivitylogs.properties.roles / wids | 呼び出し元が保持するディレクトリロールの表示名と既知のロールテンプレートのGUID | 呼び出し時に特権ロール(グローバル管理者、アプリケーション管理者など)が実行されているかどうか |
azure.aadgraphactivitylogs.properties.scopes | 呼び出しトークンのOAuthスコープ | トークンが実際に呼び出し元に付与するディレクトリ権限 |
azure.aadgraphactivitylogs.properties.client_auth_method | クライアントの認証方法(PRT、証明書、秘密鍵など) | PRTの悪用、デバイスPRTの悪用、または盗まれたクライアント認証情報の使用に関する指紋 |
azure.aadgraphactivitylogs.properties.sign_in_activity_id | 発信元のサインインとの相関ID | AAD Graph コールバックから呼び出しトークンを生成したサインインイベントにピボットします。 |
azure.aadgraphactivitylogs.properties.token_issued_at | トークンが発行されたタイムスタンプ | トークンの有効期限分析:数日前に発行されたトークンを利用した呼び出しは、古いトークン/リフレッシュトークンの悪用を示している可能性があります。 |
検出と防止
検知
AADグラフによる検出を行うための前提条件は、そもそもログが存在することです。AzureADGraphActivityLogs診断カテゴリは、Entra ID で有効にし、クエリ可能な宛先(最低限 Log Analytics ワークスペース、理想的には上記のセットアップセクションで説明されているように Elastic 取り込み用のイベントハブにも転送)にルーティングする必要があります。それが完了するまでは、この記事で説明されている呼び出しはすべてカメラに映らないところで行われ、以下の狩りはどれも発砲しません。
現時点でElasticにデータを取り込めない場合でも、診断設定を有効にしてLog Analyticsに送信してください。以下の検索クエリに相当するKQLクエリは単純明快で、追加処理を行わなくてもデータは保持されながら蓄積されていきます。
予防
ポータルには、テナント全体に適用される単一のAAD Graphキルスイッチはありません。実際のアプリケーション層制御は次のとおりです。
application.authenticationBehaviors.blockAzureADGraphAccess
アプリケーション リソースに対するアプリごとのブール値 (Microsoft Graph ベータ版、ドキュメント)。大規模なブロックとは、すべてのアプリ登録を一つずつ確認し、手動またはプログラムによってブロックすることを意味します。マイクロソフト自身の段階的な事業撤退計画は、いずれにせよ彼らのスケジュール通りに進められる。それが進むにつれて、守るべき表面積は少なくなっていく。
その間、守備側は同じ軸上で移動することができる。
-
テナント内で、 graph.windows.netのトークンを保持しているアプリケーションを監査します。必要ないものには
blockAzureADGraphAccess = true設定してください。AAD Graphに依存しているものはすべて大きな障害が発生し、これまで存在を知らなかったレガシーな自動化機能が露呈します。 -
Azure AD Graphをターゲットリソースとして、条件付きアクセスを適用します。Azure AD Graph サービス プリンシパル (
00000002-0000-0000-c000-000000000000) は標準の CA アプリ ピッカーには表示されませんが、すべてのリソースポリシーでカバーされており、カスタム セキュリティ属性フィルター アプローチを使用して個別にターゲットにすることができます。Microsoft の3 月 2026 強制変更により、これがより実用的になりました。以前は CA の強制から自動的に除外されていた低権限スコープ ( User.Read 、 People.Readなど) は、AAD Graph アクセスとして扱われるようになり、すべてのリソースポリシーが実際にそれらをゲートします。CAはトークン発行時に評価を行うため、既に有効なトークンは有効期限が切れるまで引き続き使用できます。 -
FOCIクライアント(Microsoft Teams、Microsoft Office、OneDrive、Azure PowerShellなど)にCAを適用し、攻撃者のツールがそれらを利用するようにします。管理対象かつ法令遵守に準拠したデバイスが必要です。基となるクライアントがサインインできない場合、スワップパスは崩壊します。
-
サービスプリンシパル呼び出し元の場合、 Workload Identities PremiumはサービスプリンシパルにスコープされたCAを追加します。条件は場所、ID保護リスク、認証コンテキストに限定され、唯一の許可制御はブロックです。外部コンテキストやリスクの高いコンテキストのパスを統合するのに役立ちますが、ユーザーCAのようにSPを特定のクラウドアプリにスコープするためには使用できません。
-
デバイスコードフローを必要としないユーザーに対しては、そのフローを無効にします。
roadrecon auth --device-codeは上記のパイプライン全体への最も抵抗の少ない経路であり、OAuth フィッシングで非常によく見られます。
動作検出
上記で説明したAADグラフ偵察形状を網羅する検出ルールを出荷しました。それぞれがElasticの検出ルールリポジトリに存在し、解析されたlogs-azure.aadgraphactivitylogs-*データストリームに対してネイティブに実行されます。
疑わしいユーザーエージェントによる Azure AD Graph アクセス- KQL マッチ ルール。AAD Graph が、攻撃ツール群 (Python、aiohttp、curl、Go-http-client、axios、AzureHound、BloodHound、AADIntenals など) に一致するユーザーエージェント文字列からのトラフィックを受信したときにトリガーされます。マイクロソフトの純正コンポーネントはどれもこれらのいずれかに該当しないのに対し、デフォルトのツールは該当するため、これは確かな基準信号となる。
Azure AD Graph でユーザーからの 4xx エラー率が高い- ES|QL 集計。単一の呼び出し元が、短時間内にAADグラフに対して異常に高い割合で4xx応答を生成した場合にトリガーされます。偵察やブルートフォース攻撃によるトークンの使用は、ツールが権限のないエンドポイントにアクセスしたり、所有していないオブジェクトIDを要求したり、AAD Graphに対して承認されていないクライアントIDを使用したりするため、403エラーや404エラーの連鎖を引き起こします。
異常なクライアントとユーザーによる Azure AD Graph アクセス- KQL new_terms ルール、中程度の深刻度。呼び出し元の OAuth クライアントとサインインしたユーザーのペアが、過去 14 日間で初めて AAD Graph に現れたときに発生します。FOCIスワップ、ユーザーが通常使用しないクライアントで引き換えられたフィッシングによるリフレッシュトークン、および見慣れないクライアントで使用された盗まれたトークンを検出します。Microsoftがバックエンドを所有し、Azure ADと連携することが一般的に確認されている既知のファーストパーティアプリケーションを無視します。
異常なユーザーおよびASNによるAzure ADグラフアクセス- KQLマッチルール。一般的な Microsoft / AWS / GCP / Akamai / Cloudflare の ASN 組織を除外し、そのセット外から発生した AAD Graph トラフィックにフラグを立てます。攻撃者のツールは通常、住宅用ISP、VPSプロバイダー、または匿名化ネットワークを利用しており、正当なファーストパーティ発信者とは異なるASN分布を生成します。除外するASNリストを調整することで、テナントごとに設定可能です。
Azure AD Graph 潜在的列挙 (ROADrecon) - ES|QL 集約、高深刻度。aiohttpユーザーエージェントと、単一のIDからの500件以上のAAD Graphリクエストのバーストの両方が必要です。ROADreconのgatherコマンドはデフォルトでaiohttpを使用し、すべてのディレクトリオブジェクトタイプを走査するため、この組み合わせは基本的にツール固有の特徴と言えます。追加のバースト要件により開発者プロトタイプの誤検出クラスが除外されるため、一般的な非マイクロソフトUAルールよりも深刻度が高くなります。
Entra ID OAuth デバイスコードによる Azure AD Graph 列挙へのサインイン- EQL シーケンス、重大度が高い。同じユーザーが 5 分以内に、管理されていないデバイス上で、 graph.windows.netに対してディレクトリ列挙を行い、従来の AAD Graph オーディエンス ( 00000002-0000-0000-c000-000000000000 ) へのデバイス コード サインインに成功します。デバイスコードフィッシングでは、ユーザーのパスワードやMFAに触れることなくOAuthトークンが取得されるため、攻撃者はそのトークンに基づいてユーザー、サービスプリンシパル、アプリケーション、ロール割り当て、ポリシー、テナントの詳細などのGraph情報を即座に読み取ることができ、侵害されたIDを悪用することが可能になります。クロスデータストリームシーケンスは、他のAADグラフルールが抱える単一イベントの偽陽性クラスを除去します。
AADグラフの可視性:次に何が来るのか
過去10年間の大半において、AADグラフの活動はテレメトリにおけるダークマターに相当するものだった。攻撃者のツールが繰り返しその箇所を指し示していたため、その存在は分かっていたものの、顧客は購読できる診断ストリームも、照会できるログも持っていなかった。Microsoft Graph Activity Logsは、2024年4月に一般提供開始された時点で、そのギャップの半分を埋めた。AzureADGraphActivityLogs は、2026 年初頭にようやく残りの半分を閉じました。
データが揃った今、あとは我々の責任だ。新しい診断設定を追加し、イベントハブを指定し、スタックに取り込み、検出を有効にする(または独自の検出を作成する)と、監視を開始できます。
この記事で取り上げた検出結果は、あくまで出発点に過ぎません。AAD Graphトラフィックがスタックに取り込まれ、テナント内での通常の状態がどのようなものかというベースラインが確立されれば、同じパターンが一般化されます。マイクロソフトの正規のファーストパーティ呼び出し元は、少数で識別可能なグループを形成しており、そのグループに含まれないものはすべて、より詳細な調査に値する。
その活動は常に存在していた。視界もようやく良くなった。
幸運を祈ります!
参照資料
上記の研究を通じて、以下のことが参照されました。
- Elastic Azureとの統合
- ROADtools GitHub
- ROADtools wiki
- Azure AD機能を備えたBloodHound
- AADInternals
- AADInternalsのドキュメント
- Azure AD Graph から Microsoft Graph へアプリを移行する
- アクティビティ ログの Microsoft Entra 診断設定を構成する
- Microsoft Graphのアクティビティログにアクセスする
- Microsoft Graphのアクティビティログが一般提供開始となりました。
- 待望のリンク:AADGraphActivityLogsがついに登場
- Azure AD の権限昇格 - アプリケーション管理者としてデフォルトのアプリケーション権限を引き継ぐ
- プライマリ更新トークンを使用したAzure AD SSOの悪用
Elastic Security Labsについて
Elastic Security Labsは、Elastic Securityの脅威インテリジェンス部門であり、脅威の状況に良い変化をもたらすことに専念しています。Elastic Security Labs は、戦略的、運用上、戦術的な攻撃者の目標を分析した、新たな脅威に関する公開された調査結果を提供し、その調査結果を Elastic Security に組み込まれた検出および対応機能と統合します。Elastic Security Labs の Twitter アカウント@elasticseclabsをフォローし、 www.elastic.co/ security-labs/ で調査結果をご覧ください。