2024年セキュリティの現状:競争が激化するAIの活用
先進的なサイバーセキュリティ対策を推進する組織がどのように課題を克服し、AIを活用してイノベーションを推進し、デジタルレジリエンスを強化しているかをご確認ください。
このブログは独立した公開情報であり、Microsoft社との提携によるものではなく、同社からの認定、支援、承認を受けていません。
2024年1月19日、Microsoft社はアドバイザリを公開し、M365テナントを標的とするサイバーセキュリティインシデントが発生したことを報告しました。この攻撃は、「Nobelium」や「APT29」の名でも知られる、国家が支援する脅威グループ「Midnight Blizzard」によるものと特定されました。続く1月24日、Microsoft社は、初期の発表を補足する包括的なブログ記事を投稿し、攻撃に関する詳しい所見と、攻撃者による具体的な戦術、技法、手順を公表しました。また、セキュリティ研究者のAndy Robbins氏が、ブログ記事と動画を通じて貴重な知見を提供しています。同氏の知見はセキュリティチームにとって、このインシデントをより深く理解するうえで非常に役立ちます。
このブログ記事では、Splunk脅威調査チームが、サイバーセキュリティチーム向けに、Microsoft社のブログ記事で取り上げられている攻撃チェーンの概要と、そこから考えられる実践的な検出およびハンティング戦略をご紹介します。攻撃の詳細の一部はまだ明らかになっていませんが、わかっている情報に基づいて仮説を立てて分析を行うために必要な情報を提供します。また、このインシデントに特化していないものの、類似のシナリオに適用できる、より汎用的な検出戦略についても説明します。
このセクションでは、Midnight Blizzardによる攻撃チェーンを戦術ごとに分析します。各戦術について、Microsoft社のブログ記事から引用した攻撃手順の要点を紹介してから、その検出に利用できるルールについて説明します。
ここで紹介する検出戦略は主に、Office 365の統合監査ログを基に作成され、Splunk調査サイトの「NOBELIUM Group (NOBELIUMグループ)」分析に詳細が記載されています。また、Office 365分析ストーリーの「Office 365 Account Takeover (Office 365アカウントの乗っ取り)」、「Office 365 Persistence Mechanisms (Office 365永続化メカニズム)」、「Office 365 Collection Techniques (Office 365収集技法)」にも一部掲載されています。主要なデータソースとしてEntra IDログを使用したい場合は、それぞれに対応するEntra ID検出ルールが「Azure AD Account Takeover (Azure ADアカウントの乗っ取り)」、「Azure AD Persistence (Azure AD永続化)」、「Azure AD Persistence (Azure AD永続化)」に掲載されています。
Splunkが公開しているattack_dataオープンソースプロジェクトには、この記事でシミュレートしているすべての攻撃技法のデータセットが含まれます。このデータセットは、検出エンジニアが検出戦略の開発や検証を行うときに役立ちます。特に、独自にシミュレーションを実施できない場合は重要なリソースになります。
Midnight Blizzardは、パスワードスプレー攻撃を用いて、本番環境ではなく多要素認証(MFA)が有効になっていないテスト用のレガシーテナントのアカウントを乗っ取ることに成功しました。 |
統合監査ログとEntra IDログのどちらでもエラーコード50126を監視することで、短時間の間に同じ送信元IPアドレスを使う多数のユーザーが認証に失敗する従来型のパスワードスプレー攻撃を検出できます。
O365 Multiple Users Failing To Authenticate From Ip
`o365_management_activity` Workload=AzureActiveDirectory Operation=UserLoginFailed ErrorNumber=50126
| bucket span=5m _time
| stats dc(user) as unique_accounts values(user) as user values(LogonError) as LogonError
values(signature) as signature values(UserAgent) as UserAgent by _time, src_ip
| where unique_accounts > 10
最近では、さまざまな国のIPアドレスで構成される分散ネットワークを使ってセキュリティ対策を回避する、ステルス性の高いパスワードスプレー攻撃も確認されています。この場合、上述の分析ロジックをすり抜ける可能性があります。そのため、別の戦略を用意しました。この検出ルールでは、同じ特徴を持つ認証の試行が短時間で急増する状況を監視します。
この分析では、失敗したログイン試行の主要なメトリクスとして以下の値を算出しています。
これらのメトリクスのしきい値をカスタマイズすることで、通常の動作から逸脱したパターンを見つけ出すことができます。
O365 Multi-Source Failed Authentications Spike
`o365_management_activity` Workload=AzureActiveDirectory Operation=UserLoginFailed ErrorNumber=50126
| bucket span=5m _time
| eval uniqueIPUserCombo = src_ip . "-" . user
| stats dc(uniqueIPUserCombo) as uniqueIpUserCombinations, dc(user) as uniqueUsers,
dc(src_ip) as uniqueIPs, values(user) as user, values(src_ip) as ips, values(user_agent) as user_agents by _time
| where uniqueIpUserCombinations > 20 AND uniqueUsers > 20 AND uniqueIPs > 20
Midnight Blizzardは、初期アクセスで固めた足場を利用して、Microsoft社内環境の特権アクセス権を持つテスト用のレガシーOAuthアプリケーションを探し出し、侵害しました。 |
攻撃者がレガシーOAuthアプリケーションを侵害し、そのアプリケーションを通じて不正操作を行うには、設定を変更し、アプリケーション登録オブジェクトに新しい認証情報を追加する必要があります。これらのアクティビティは、「Update application - Certificates and secrets management」イベントを追跡することで監視できます。このイベントに注目すれば、Entra IDの権限昇格攻撃でよく使われるこの戦術を監視し、問題に対応できます。
O365 Service Principal New Client Credentials
`o365_management_activity` Workload=AzureActiveDirectory Operation="Update
application*Certificates and secrets management "
| stats earliest(_time) as firstTime latest(_time) as lastTime by user
ModifiedProperties{}.NewValue object ObjectId
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
攻撃者は、認証情報を追加した後、その権限を利用するために、アプリケーション登録と関連付けられたサービスプリンシパルとして認証を行う必要があります。ここで、デフォルトでは統合監査ログにユーザー対話型認証のイベントしか記録されず、サービスプリンシパル認証は記録されないことに注意が必要です。これらのアクティビティを効果的に監視するには、Entra IDログの「ServicePrincipalSignInLogs」カテゴリを調べる必要があります。
どのサービスプリンシパルが組織内のどこから認証を行っているかがわかれば、不正アクセスやサービスの悪用を検出するのに役立ちます。多数のアプリケーションが展開されている大規模な環境で、この関係を調べるのは容易ではないでしょう。それでも、脅威ハンティングの演習として送信元IPアドレスと関連するサービスプリンシパルを追跡し、インベントリに記録する手間をかける価値はあります。
Azure AD Service Principal Authentication
`azure_monitor_aad` operationName="Sign-in activity" category=ServicePrincipalSignInLogs
| rename properties.* as *
| stats count earliest(_time) as firstTime latest(_time) as lastTime by user, user_id, src_ip,
resourceDisplayName, resourceId
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
Midnight Blizzardは、初期アクセスで固めた足場を利用して、Microsoft社内環境の特権アクセス権を持つテスト用のレガシーOAuthアプリケーションを探し出し、侵害しました。 |
侵害されたアプリケーションに高い権限が付与されている場合、必ずしも攻撃が原因とは限りません。攻撃の前から付与されていた可能性もあります。IDに必要以上の権限が割り当てられるのは、多くの組織でよく起こる問題です。M365とEntra IDのエコシステムでは、Entra IDのロールとAPIの権限(GraphやExchange Onlineなど)を監視することが非常に重要です。
これらのイベントを効果的に監視するには、「Add member to role」と「Update application」の各イベントを追跡します。「Global Administrator」や「Privileged Role Administrator」などの重要なロールと、「Application.ReadWrite.All」、「AppRoleAssignment.ReadWrite.All」、「RoleManagement.ReadWrite.Directory」など攻撃に使われやすいAPIの権限を重点的に監視するのも良い方法です。もちろん、これらがすべてではなく、組織の状況に合わせて監視対象を検討する必要があります。
O365 High Privilege Role Granted
`o365_management_activity` Operation="Add member to role."
Workload=AzureActiveDirectory
| eval role_id = mvindex('ModifiedProperties{}.NewValue',2)
| eval role_name = mvindex('ModifiedProperties{}.NewValue',1)
| where role_id IN ("29232cdf-9323-42fd-ade2-1d097af3e4de",
"f28a1f50-f6e7-4571-818b-6a12f2af6b6c", "62e90394-69f5-4237-9190-012177145e10")
| stats earliest(_time) as firstTime latest(_time) as lastTime by user Operation ObjectId
role_name
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
O365 Privileged Graph API Permission Assigned
`o365_management_activity` Workload=AzureActiveDirectory Operation="Update application."
| eval newvalue = mvindex('ModifiedProperties{}.NewValue',0)
| ssrc input=newvalue
| search
"{}.RequiredAppPermissions{}.EntitlementId"="1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9" OR
"{}.RequiredAppPermissions{}.EntitlementId"="06b708a9-e830-4db3-a914-8e69da51d44f"
OR "{}.RequiredAppPermissions{}.EntitlementId"="9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8"
| eval Permissions = '{}.RequiredAppPermissions{}.EntitlementId'
| stats count earliest(_time) as firstTime latest(_time) as lastTime values(Permissions)
by user, object, user_agent, Operation
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
攻撃者は悪質なOAuthアプリケーションを新たに作成します。 |
Entra ID環境に新しいOAuthアプリケーションが作成されると、「Add Application」イベントと「Add Service Principal」イベントが生成されます。運用環境では正規のイベントが頻繁に生成されるため、アプリケーション作成の監視は負担が大きいかもしれません。
その場合でも、短時間に複数のアプリケーションが作成される状況は監視しておくとよいでしょう。さらに、今回の分析では統合監査ログの「Actor」フィールドを調べることで、アプリケーションを作成したのがユーザーかサービスプリンシパルかを確認できます。この追加のコンテキストを利用して、目的の脅威検出の分析を作成しました。
O365 Multiple Service Principals Created by User
`o365_management_activity` Workload=AzureActiveDirectory Operation="Add service
principal."
| bucket span=10m _time
| eval len=mvcount('Actor{}.ID')
| eval userType = mvindex('Actor{}.ID',len-1)
| search userType = "User"
| eval displayName = object
| stats count earliest(_time) as firstTime latest(_time) as lastTime values(displayName) as
displayName dc(displayName) as unique_apps by src_user
| where unique_apps > 3
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
O365 Multiple Service Principals Created by SP
`o365_management_activity` Workload=AzureActiveDirectory Operation="Add service principal."
| bucket span=10m _time
| eval len=mvcount('Actor{}.ID')
| eval userType = mvindex('Actor{}.ID',len-1)
| search userType = "ServicePrincipal"
| eval displayName = object
| stats count earliest(_time) as firstTime latest(_time) as lastTime values(displayName) as
displayName dc(displayName) as unique_apps by src_user
| where unique_apps > 3
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
攻撃者はその後、テスト用のレガシーOAuthアプリケーションを使って、Office 365 Exchange Onlineのfull_access_as_appロールを自らに割り当てました。このロールがあればメールボックスにアクセスできます。 |
Midnight Blizzardは、Exchange Onlineの高いAPI権限を自らに割り当てて、メールの収集段階に進みました。Azureポータルを使って高いAPI権限を割り当てる通常の手順では、2つの重大なイベントが生成されます。
管理者による組織レベルの権限付与は、「テナント全体の管理者の同意」と呼ばれ、特に重大です。この同意により、アプリケーションが組織全体にわたる処理を実行できるようになるため、監視は必須です。そこで、「ModifiedProperties」フィールドを監視してテナント全体の管理者の同意を検出するための分析を作成しました。
O365 Tenant Wide Admin Consent Granted
`o365_management_activity` Operation="Consent to application."
| eval new_field=mvindex('ModifiedProperties{}.NewValue', 4)
| rex field=new_field "ConsentType: (?[^\,]+)"
| rex field=new_field "Scope: (?[^\,]+)"
| search ConsentType = "AllPrincipals"
| stats count min(_time) as firstTime max(_time) as lastTime by Operation, user, object,
ObjectId, ConsentType, Scope
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
ただし、Microsoft社が公開している攻撃チェーンでは「Update Application」イベントや「Consent to Application」イベントが発生しなかった可能性があります。上述の引用は、権限割り当ての標準的な手段であるAzureポータルを攻撃者が使用しなかったことを示唆しています。代わりに、レガシーアプリケーションのサービスプリンシパル権限を悪用して権限をプログラムで変更し、通常の同意手順を回避したと考えられます。
この方法を深く理解するために、私たちはMicrosoft Graph PowerShell SDKの「New-MgServicePrincipalAppRoleAssignedTo」コマンドレットを使ってこの手順を再現してみました。その結果、通常発生する2つのイベントの代わりに「Add app role assignment to service principal」イベントのみが生成され、私たちの仮説が正しかったことが証明されました。
$servicePrincipal = Get-MgServicePrincipal -Filter "displayName eq 'MaliciousApp'"
$EolServicePrincipal = Get-MgServicePrincipal -Filter "servicePrincipalType eq 'Application'
and displayName eq 'Office 365 Exchange Online'"
$appRole = $EolServicePrincipal.AppRoles | Where-Object { $_.Value -eq
"full_access_as_app" -and $_.AllowedMemberTypes -contains "Application" }
$params = @{
principalId = $servicePrincipal.Id
resourceId = $EolServicePrincipal.Id
appRoleId = $appRole.Id
}
New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $servicePrincipal.Id
-BodyParameter $params
ログで「Add app role assignment to service principal」イベントを確認すると、「Actor」フィールドを調べることで操作を実行したのがサービスプリンシパルか管理者ユーザーかを判断できることがわかりました。これを基に、サービスプリンシパルがAPI権限を他のサービスプリンシパルにプログラムで割り当てることによって、管理者の同意プロセスを回避するシナリオを検出するための新しい分析を作成しました。
O365 Admin Consent Bypassed by Service Principal
`o365_management_activity` Workload=AzureActiveDirectory Operation="Add app role
assignment to service principal."
| eval len=mvcount('Actor{}.ID')
| eval userType = mvindex('Actor{}.ID',len-1)
| eval roleId = mvindex('ModifiedProperties{}.NewValue', 0)
| eval roleValue = mvindex('ModifiedProperties{}.NewValue', 1)
| eval roleDescription = mvindex('ModifiedProperties{}.NewValue', 2)
| eval dest_user = mvindex('Target{}.ID', 0)
| search userType = "ServicePrincipal"
| eval src_user = user
| stats count earliest(_time) as firstTime latest(_time) as lastTime by src_user dest_user
roleId roleValue roleDescription
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
Midnight Blizzardは、これらの悪質なOAuthアプリケーションを利用してMicrosoft Exchange Onlineと標的のMicrosoft社内メールアカウントへの認証を行いました。 |
適切な権限を手に入れた攻撃者は、社内メールアカウントを使ってメールの情報を収集し始めました。このアクティビティは、統合監査ログの「Mailitemsaccessed」イベントを監視することで追跡できます。当初、このログを利用できるのはE5ライセンスのみでしたが、現在では標準のM365ユーザーも利用できます。
このイベントで重要なのは「ClientAppId」フィールドで、ユーザーに代わってアクセスを実行したMicrosoft EntraアプリケーションのIDを示します。OAuthアプリケーション、Exchange Web Services、PowerShell、Pythonクライアントを使ったこの技法のシミュレーションでは「ClientAppId」が常に「47629505-c2b6-4a80-adb1-9b3a3d233b7b」でした。
ただし、このGUIDがExchange Web Servicesに実際に割り当てられることを裏付けるMicrosoft社のドキュメントは見つかりませんでした。そこで誤検知を避けるため、代わりに、操作の実行に使われたメールクライアントに関する情報が格納される「ClientInfoString」フィールドを使用しました。実験では、このフィールドは常に同じ文字列で始まっていました。
O365 OAuth App Mailbox Access via EWS
`o365_management_activity` Workload=Exchange Operation=MailItemsAccessed AppId=*
ClientAppId=*
| regex ClientInfoString="^Client=WebServices;ExchangeWebServices"
| stats count earliest(_time) as firstTime latest(_time) as lastTime values(ClientIPAddress)
as src_ip by user ClientAppId OperationCount AppId ClientInfoString
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
Midnight Blizzardは今回、メールの収集にExchange Web Servicesを使用しましたが、攻撃者がこのシナリオで重要なMicrosoft Graph API権限を取得し、別の方法でメールを収集するシナリオを想定しておく必要があります。その想定で、Graph APIによるメールボックスへのアクセスを検出する別の分析も作成しました。
O365 OAuth App Mailbox Access via Graph API
`o365_management_activity` Workload=Exchange Operation=MailItemsAccessed AppId=*
AppId=00000003-0000-0000-c000-000000000000
| stats count earliest(_time) as firstTime latest(_time) as lastTime values(ClientIPAddress)
by user ClientAppId OperationCount AppId
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
監視すべき挙動はもうひとつあります。それは、OAuthアプリケーションがプログラムでExchange Web ServicesやMicrosoft GraphなどのAPIを介し、短時間で複数のメールボックスにアクセスするシナリオです。ジャーナリングやコンプライアンス目的など、このようなアクセスが正当な理由で必要になることもありますが、通常、このようにメールボックスに広範にアクセスするアプリケーションは例外的であり、きちんと把握してインベントリに記録しておく必要があります。
O365 Multiple Mailboxes Accessed via API
`o365_management_activity` Workload=Exchange Operation=MailItemsAccessed AppId=*
ClientAppId=*
| bucket span=10m _time
| eval matchRegex=if(match(ClientInfoString,
"^Client=WebServices;ExchangeWebServices"), 1, 0)
| search (AppId="00000003-0000-0000-c000-000000000000" OR matchRegex=1)
| stats values(ClientIPAddress) as src_ip dc(user) as unique_mailboxes values(user) as user
by _time ClientAppId ClientInfoString
| where unique_mailboxes > 5
クラウドコンピューターは進化し続けており、この記事で説明したような新しい攻撃ベクトルが次々と現れています。クラウド環境に設定ミスがあると、攻撃者がその不備を突いてテナント全体を乗っ取る可能性もあります。防御側は、従来のエンドポイント重視の戦略から進化し、クラウドを標的とする新しい脅威について理解を深めることが重要です。
Splunk脅威調査チームは引き続き、検出戦略、SOARプレイブック、ブログ記事、オープンソースプロジェクトなどのコンテンツの提供を通じて、サイバーセキュリティコミュニティの支援に取り組んでまいります。Midnight Blizzardのような、国家が支援するグループの攻撃に対するセキュリティ態勢を強化し、変化し続けるサイバー脅威に対応するために、ぜひこのブログ記事をお役立てください。
research.splunk.comには、Splunk脅威調査チームが公開しているすべてのセキュリティコンテンツがまとめられています。これらのコンテンツは、Enterprise Security Content Updates AppまたはSplunk Security Essentials Appを使って導入できます。
Splunkプラットフォームは、データを行動へとつなげる際に立ちはだかる障壁を取り除いて、オブザーバビリティチーム、IT運用チーム、セキュリティチームの能力を引き出し、組織のセキュリティ、レジリエンス(回復力)、イノベーションを強化します。
Splunkは、2003年に設立され、世界の21の地域で事業を展開し、7,500人以上の従業員が働くグローバル企業です。取得した特許数は1,020を超え、あらゆる環境間でデータを共有できるオープンで拡張性の高いプラットフォームを提供しています。Splunkプラットフォームを使用すれば、組織内のすべてのサービス間通信やビジネスプロセスをエンドツーエンドで可視化し、コンテキストに基づいて状況を把握できます。Splunkなら、強力なデータ基盤の構築が可能です。