关于 detecting-azure-service-principal-abuse
面向 SOC 分析人员和威胁搜寻人员的 Azure 服务主体滥用检测技能,提供 KQL、SPL 查询与调查步骤,用于识别凭据新增、权限提升和异常枚举等行为。
主要功能
- 01检测新增服务主体凭据
- 02识别特权角色分配
- 03监控服务主体枚举
- 04发现异常应用授权
- 05调查所有者与登录活动
适用场景
- 01调查疑似服务主体入侵
- 02构建 SIEM 威胁检测查询
- 03检查 Entra ID 权限滥用路径
- 04验证云身份监控覆盖
安装
复制下面的命令,在终端中运行。
$
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 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py详细介绍
检测 Azure 服务主体滥用
概述
Azure 服务主体是应用程序、服务和自动化工具用来访问 Azure 资源的身份对象。攻击者利用服务主体进行权限提升、横向移动和持久化访问。主要的滥用模式包括:向现有主体添加凭据、分配特权角色、绕过管理员同意,以及枚举服务主体以寻找攻击路径。应用程序所有权授予管理凭据和配置权限的能力,从而形成隐藏的权限提升路径。
何时使用
- 在调查需要检测 Azure 服务主体滥用的安全事件时
- 在为该领域构建检测规则或威胁狩猎查询时
- 当 SOC 分析师需要针对此类分析的结构化流程时
- 在验证相关攻击技术的安全监控覆盖范围时
先决条件
- 具有 Microsoft Entra ID P2 许可证的 Azure 订阅
- 对 Azure AD 审核日志和登录日志的访问权限
- 用于基于 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 分析规则进行监控
为以下情况创建分析规则:
- 新增服务主体凭据
- 向服务主体分配特权角色
- 批量枚举服务主体
- 向未知应用程序授予管理员同意
- 来自异常位置的服务主体登录
MITRE ATT&CK 映射
| 技术 | ID | 描述 |
|---|---|---|
| 账户操纵:额外的云凭据 | T1098.001 | 向服务主体添加凭据 |
| 有效账户:云账户 | T1078.004 | 使用被入侵的服务主体 |
| 账户发现:云账户 | T1087.004 | 枚举服务主体 |
| 窃取应用程序访问令牌 | T1528 | 通过服务主体窃取 OAuth 令牌 |
参考资料
- Splunk 检测:Azure AD 服务主体滥用
- Semperis:Entra ID 中的服务主体所有权滥用
- MITRE ATT&CK 云矩阵
- Microsoft:在 Entra ID 中保护服务主体
评论
支持 Markdown