mcpField
D
detecting-azure-service-principal-abuse

detecting-azure-service-principal-abuse

github.com/mukul975セキュリティ35.2k58 回インストール8 週間前に更新
リポジトリ

detecting-azure-service-principal-abuse について

Azureサービスプリンシパルの悪用を調査するSOCアナリストや脅威ハンター向けのスキルです。資格情報の追加、権限昇格、不審な列挙を検出するKQL・SPLと調査手順を提供します。

主な機能

  1. 01サービスプリンシパル資格情報の追加検出
  2. 02特権ロール割り当ての特定
  3. 03サービスプリンシパル列挙の監視
  4. 04不審なアプリ同意の検出
  5. 05所有者とサインインの調査

活用シーン

  1. 01侵害が疑われるサービスプリンシパルの調査
  2. 02SIEM脅威検出クエリの作成
  3. 03Entra IDの権限悪用経路の確認
  4. 04クラウドID監視範囲の検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill detecting-azure-service-principal-abuse

インストール後、Claude Code で/detecting-azure-service-principal-abuseを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

詳細

Azure サービスプリンシパルの悪用を検出する

概要

Azure サービスプリンシパルは、アプリケーション、サービス、自動化ツールが Azure リソースにアクセスするために使用する ID オブジェクトです。攻撃者は、権限昇格、横展開、永続的なアクセスのためにサービスプリンシパルを悪用します。主な悪用パターンには、既存のサービスプリンシパルへの認証情報の追加、特権ロールの割り当て、管理者の同意の回避、攻撃経路を探るためのサービスプリンシパルの列挙などがあります。アプリケーションの所有権があると、認証情報を管理し、権限を設定できるため、気づかれにくい権限昇格経路が生まれます。

使用する場面

  • Azure サービスプリンシパルの悪用を検出する必要があるセキュリティインシデントを調査する場合
  • この分野の検出ルールや脅威ハンティングクエリを作成する場合
  • SOC アナリストがこの種の分析に関する体系的な手順を必要とする場合
  • 関連する攻撃手法に対するセキュリティ監視の対応状況を検証する場合

前提条件

  • Microsoft Entra ID P2 ライセンスを備えた Azure サブスクリプション
  • Azure AD Audit Logs および Sign-in Logs へのアクセス権
  • SIEM ベースの検出に使用する Microsoft Sentinel または Splunk
  • 調査用の Microsoft Graph API 権限
  • 最低限、グローバル閲覧者またはセキュリティ閲覧者のロール

主な悪用パターン

1. サービスプリンシパルへの新しい認証情報の追加

攻撃者は、新しいクライアントシークレットや証明書を追加して、永続的なアクセスを得ます。

検出クエリ(KQL - Sentinel):

AuditLogs
| where OperationName has "Add service principal credentials"
    or OperationName has "Update application - Certificates and secrets management"
| extend InitiatedBy = tostring(InitiatedBy.user.userPrincipalName)
| extend TargetSP = tostring(TargetResources[0].displayName)
| extend TargetSPId = tostring(TargetResources[0].id)
| project TimeGenerated, InitiatedBy, OperationName, TargetSP, TargetSPId
| sort by TimeGenerated desc

検出クエリ(SPL - Splunk):

index=azure sourcetype="azure:aad:audit"
operationName="Add service principal credentials"
    OR operationName="Update application*Certificates and secrets*"
| stats count by initiatedBy.user.userPrincipalName, targetResources{}.displayName, _time
| sort -_time
2. サービスプリンシパルへの特権ロールの割り当て
AuditLogs
| where OperationName == "Add member to role"
| extend RoleName = tostring(TargetResources[0].modifiedProperties[1].newValue)
| where RoleName has_any ("Global Administrator", "Application Administrator",
    "Privileged Role Administrator", "Cloud Application Administrator")
| extend TargetSP = tostring(TargetResources[0].displayName)
| extend InitiatedBy = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, InitiatedBy, TargetSP, RoleName, OperationName
3. サービスプリンシパルの列挙の検出
MicrosoftGraphActivityLogs
| where RequestMethod == "GET"
| where RequestUri has "/servicePrincipals"
| summarize RequestCount = count() by UserAgent, IPAddress, bin(TimeGenerated, 1h)
| where RequestCount > 10
| sort by RequestCount desc
4. 管理者の同意の回避
AuditLogs
| where OperationName == "Consent to application"
| extend ConsentType = tostring(TargetResources[0].modifiedProperties[4].newValue)
| where ConsentType has "AllPrincipals"
| extend AppName = tostring(TargetResources[0].displayName)
| extend InitiatedBy = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, InitiatedBy, AppName, ConsentType
5. OAuth アプリの権限昇格
AuditLogs
| where OperationName == "Add app role assignment to service principal"
| extend AppRoleValue = tostring(TargetResources[0].modifiedProperties[1].newValue)
| where AppRoleValue has_any ("RoleManagement.ReadWrite.Directory",
    "Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All",
    "Directory.ReadWrite.All", "Mail.ReadWrite")
| extend TargetApp = tostring(TargetResources[0].displayName)
| project TimeGenerated, TargetApp, AppRoleValue, CorrelationId

調査手順

ステップ 1:侵害されたサービスプリンシパルを特定する
# List service principals with recently added credentials
Connect-MgGraph -Scopes "Application.Read.All"

$suspiciousSPs = Get-MgServicePrincipal -All | ForEach-Object {
    $sp = $_
    $creds = Get-MgServicePrincipalPasswordCredential -ServicePrincipalId $sp.Id
    $recentCreds = $creds | Where-Object { $_.StartDateTime -gt (Get-Date).AddDays(-7) }
    if ($recentCreds) {
        [PSCustomObject]@{
            DisplayName = $sp.DisplayName
            AppId = $sp.AppId
            ObjectId = $sp.Id
            NewCredsCount = $recentCreds.Count
            LatestCredAdded = ($recentCreds | Sort-Object StartDateTime -Descending | Select-Object -First 1).StartDateTime
        }
    }
}
$suspiciousSPs | Sort-Object LatestCredAdded -Descending
ステップ 2:サービスプリンシパルのロール割り当てを確認する
# Check role assignments for a specific service principal
$spId = "<service-principal-object-id>"
Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $spId | ForEach-Object {
    $resource = Get-MgServicePrincipal -ServicePrincipalId $_.ResourceId
    [PSCustomObject]@{
        AppRoleId = $_.AppRoleId
        ResourceDisplayName = $resource.DisplayName
        CreatedDateTime = $_.CreatedDateTime
    }
}
ステップ 3:アプリケーションの所有権を確認する
# List owners of all applications (ownership = credential control)
Get-MgApplication -All | ForEach-Object {
    $app = $_
    $owners = Get-MgApplicationOwner -ApplicationId $app.Id
    foreach ($owner in $owners) {
        [PSCustomObject]@{
            AppName = $app.DisplayName
            AppId = $app.AppId
            OwnerUPN = $owner.AdditionalProperties.userPrincipalName
            OwnerType = $owner.AdditionalProperties.'@odata.type'
        }
    }
} | Where-Object { $_.OwnerUPN -ne $null }
ステップ 4:サインインアクティビティを確認する
AADServicePrincipalSignInLogs
| where ServicePrincipalId == "<target-sp-id>"
| project TimeGenerated, ServicePrincipalName, IPAddress, Location,
    ResourceDisplayName, Status.errorCode
| sort by TimeGenerated desc

予防策

アプリケーション登録を制限する
# Disable user ability to register applications
Update-MgPolicyAuthorizationPolicy -DefaultUserRolePermissions @{
    AllowedToCreateApps = $false
}
アプリの同意ポリシーを設定する
# Require admin approval for all app consent requests
New-MgPolicyPermissionGrantPolicy -Id "admin-only-consent" `
    -DisplayName "Admin Only Consent" `
    -Description "Only admins can consent to applications"
Microsoft Sentinel Analytics Rules で監視する

以下に対する分析ルールを作成します。

  • サービスプリンシパルへの新しい認証情報の追加
  • サービスプリンシパルへの特権ロールの割り当て
  • サービスプリンシパルの一括列挙
  • 不明なアプリケーションへの管理者の同意の付与
  • 通常とは異なる場所からのサービスプリンシパルのサインイン

MITRE ATT&CK との対応

手法ID説明
アカウント操作:追加のクラウド認証情報T1098.001サービスプリンシパルへの認証情報の追加
有効なアカウント:クラウドアカウントT1078.004侵害されたサービスプリンシパルの使用
アカウント探索:クラウドアカウントT1087.004サービスプリンシパルの列挙
アプリケーションアクセストークンの窃取T1528サービスプリンシパルを介した OAuth トークンの窃取

参考資料

  • Splunk Detection:Azure AD Service Principal Abuse
  • Semperis:Entra ID におけるサービスプリンシパルの所有権の悪用
  • MITRE ATT&CK Cloud Matrix
  • Microsoft:Entra ID におけるサービスプリンシパルの保護

コメント