使用 Sentinel 构建云 SIEM 是做什么的?
何时使用
- 当为多云环境建立集中式安全运营中心时
- 当从传统 SIEM 平台(Splunk、QRadar)迁移到云原生架构时
- 当为云特定威胁构建自动化事件响应工作流时
- 当跨 PB 级安全遥测数据执行大规模威胁搜寻时
- 当将威胁情报源与云安全日志分析集成时
请勿使用于仅限 AWS 的环境(Security Hub 和 GuardDuty 已足够)、需要 EDR 功能的端点检测(使用 Defender for Endpoint)或合规性态势监控(请参阅 building-cloud-security-posture-management)。
前提条件
- 具有在 Log Analytics 工作区上启用 Microsoft Sentinel 的 Azure 订阅
- 目标日志源的数据连接器权限(AWS CloudTrail、Azure Activity、GCP)
- 用于自动化响应剧本的 Logic Apps 或 Azure Functions
- 具备编写检测规则和搜寻查询所需的 KQL(Kusto 查询语言)能力
工作流
步骤 1:预配 Sentinel 工作区和数据连接器
创建一个针对安全数据优化的 Log Analytics 工作区,并启用用于多云数据引入的数据连接器。
# 创建 Log Analytics 工作区
az monitor log-analytics workspace create \
--resource-group security-rg \
--workspace-name sentinel-workspace \
--location eastus \
--retention-time 365 \
--sku PerGB2018
# 在工作区上启用 Microsoft Sentinel
az sentinel onboarding-state create \
--resource-group security-rg \
--workspace-name sentinel-workspace
# 启用 AWS CloudTrail 连接器
az sentinel data-connector create \
--resource-group security-rg \
--workspace-name sentinel-workspace \
--data-connector-id aws-cloudtrail \
--kind AmazonWebServicesCloudTrail \
--aws-cloud-trail-data-connector '{
"awsRoleArn": "arn:aws:iam::123456789012:role/SentinelCloudTrailRole",
"dataTypes": {"logs": {"state": "Enabled"}}
}'
# 启用 Azure AD 登录和审核日志
az sentinel data-connector create \
--resource-group security-rg \
--workspace-name sentinel-workspace \
--data-connector-id azure-ad \
--kind AzureActiveDirectory \
--azure-active-directory '{
"dataTypes": {
"alerts": {"state": "Enabled"},
"signinLogs": {"state": "Enabled"},
"auditLogs": {"state": "Enabled"}
}
}'
步骤 2:编写 KQL 检测规则
使用 Kusto 查询语言创建分析规则以检测特定于云的威胁。将每个规则映射到 MITRE ATT&CK 技术。
// 检测不可能旅行 - 从地理距离遥远的位置登录
let timeframe = 1h;
let distance_threshold = 500; // km
SigninLogs
| where TimeGenerated > ago(timeframe)
| where ResultType == 0 // 仅成功登录
| project TimeGenerated, UserPrincipalName, IPAddress, Location,
Latitude = toreal(LocationDetails.geoCoordinates.latitude),
Longitude = toreal(LocationDetails.geoCoordinates.longitude)
| sort by UserPrincipalName asc, TimeGenerated asc
| extend PrevLatitude = prev(Latitude, 1), PrevLongitude = prev(Longitude, 1),
PrevTime = prev(TimeGenerated, 1), PrevUser = prev(UserPrincipalName, 1)
| where UserPrincipalName == PrevUser
| extend TimeDiff = datetime_diff('minute', TimeGenerated, PrevTime)
| where TimeDiff < 60
| extend Distance = geo_distance_2points(Longitude, Latitude, PrevLongitude, PrevLatitude) / 1000
| where Distance > distance_threshold
| project TimeGenerated, UserPrincipalName, IPAddress, Location, Distance, TimeDiff
// 从 CloudTrail 检测 AWS IAM 凭证滥用
AWSCloudTrail
| where TimeGenerated > ago(24h)
| where EventName in ("ConsoleLogin", "AssumeRole", "GetSessionToken")
| where ErrorCode == ""
| summarize LoginCount = count(), DistinctIPs = dcount(SourceIpAddress),
IPList = make_set(SourceIpAddress, 10)
by UserIdentityArn, bin(TimeGenerated, 1h)
| where DistinctIPs > 3
| project TimeGenerated, UserIdentityArn, LoginCount, DistinctIPs, IPList
// 检测大规模 S3 对象删除(潜在的勒索软件)
AWSCloudTrail
| where TimeGenerated > ago(1h)
| where EventName == "DeleteObject" or EventName == "DeleteObjects"
| summarize DeleteCount = count(), BucketsAffected = dcount(RequestParameters_bucketName)
by UserIdentityArn, bin(TimeGenerated, 10m)
| where DeleteCount > 100
| project TimeGenerated, UserIdentityArn, DeleteCount, BucketsAffected
步骤 3:使用 Logic Apps 构建 SOAR 剧本
创建自动化响应剧本,当分析规则触发事件时执行。常见操作包括阻止用户、隔离资源和用威胁情报丰富警报。
{
"definition": {
"triggers": {
"Microsoft_Sentinel_incident": {
"type": "ApiConnectionWebhook",
"inputs": {
"body": {"incidentArmId": "subscriptions/@{triggerBody()?['workspaceInfo']?['SubscriptionId']}/resourceGroups/@{triggerBody()?['workspaceInfo']?['ResourceGroupName']}/providers/Microsoft.OperationalInsights/workspaces/@{triggerBody()?['workspaceInfo']?['WorkspaceName']}/providers/Microsoft.SecurityInsights/Incidents/@{triggerBody()?['object']?['properties']?['incidentNumber']}"},
"host": {"connection": {"name": "@parameters('$connections')['microsoftsentinel']['connectionId']"}}
}
}
},
"actions": {
"Get_incident_entities": {
"type": "ApiConnection",
"inputs": {"method": "post", "path": "/Incidents/entities"}
},
"For_each_account_entity": {
"type": "Foreach",
"foreach": "@body('Get_incident_entities')?['Accounts']",
"actions": {
"Disable_Azure_AD_user": {
"type": "ApiConnection",
"inputs": {
"method": "PATCH",
"path": "/v1.0/users/@{items('For_each_account_entity')?['AadUserId']}",
"body": {"accountEnabled": false}
}
},
"Add_comment_to_incident": {
"type": "ApiConnection",
"inputs": {
"body": {"message": "用户 @{items('For_each_account_entity')?['Name']} 已被自动化剧本禁用"}
}
}
}
}
}
}
}
步骤 4:配置 Sentinel 数据湖以进行长期搜寻
启用 Sentinel 数据湖以实现 PB 级日志保留,并使用 KQL 和 SQL 端点进行高级威胁搜寻。
// 威胁搜寻查询:检测跨 AWS 账户的横向移动
let suspicious_roles = AWSCloudTrail
| where TimeGenerated > ago(7d)
| where EventName == "AssumeRole"
| extend AssumedRoleArn = tostring(parse_json(RequestParameters).roleArn)
| where AssumedRoleArn contains "cross-account" or AssumedRoleArn contains "admin"
| summarize AssumeCount = count(), UniqueSourceAccounts = dcount(RecipientAccountId)
by UserIdentityArn, AssumedRoleArn
| where AssumeCount > 10 and UniqueSourceAccounts > 2;
suspicious_roles
| join kind=inner (
AWSCloudTrail
| where TimeGenerated > ago(7d)
| where EventName in ("RunInstances", "CreateFunction", "PutBucketPolicy")
) on UserIdentityArn
| project TimeGenerated, UserIdentityArn, AssumedRoleArn, EventName, SourceIpAddress
步骤 5:集成威胁情报
连接威胁情报提供商并创建基于指标匹配的规则,以检测与已知恶意基础设施的通信。
# 启用 Microsoft 威胁情报连接器
az sentinel data-connector create \
--resource-group security-rg \
--workspace-name sentinel-workspace \
--data-connector-id microsoft-ti \
--kind MicrosoftThreatIntelligence \
--microsoft-threat-intelligence '{
"dataTypes": {"microsoftEmergingThreatFeed": {"lookbackPeriod": "2025-01-01T00:00:00Z", "state": "Enabled"}}
}'
// 将网络指标与云流日志进行匹配
let TI_IPs = ThreatIntelligenceIndicator
| where TimeGenerated > ago(30d)
| where isnotempty(NetworkIP)
| distinct NetworkIP;
AzureNetworkAnalytics_CL
| where TimeGenerated > ago(24h)
| where DestIP_s in (TI_IPs)
| project TimeGenerated, SrcIP_s, DestIP_s, DestPort_d, FlowType_s
关键概念
| 术语 | 定义 |
|---|---|
| KQL | Kusto 查询语言,Microsoft Sentinel 的主要查询语言,用于搜索、分析和可视化安全数据 |
| 分析规则 | Sentinel 中的检测逻辑,它按计划评估日志数据,并在条件匹配时创建事件 |
| SOAR 剧本 | 由事件触发的自动化工作流,用于执行响应操作,如阻止账户、丰富警报或通知团队 |
| 数据连接器 | 将安全日志从云服务、身份提供商和第三方工具引入 Sentinel 的集成模块 |
| Sentinel 数据湖 | PB 级存储层,提供长期日志保留,具有 KQL 和 SQL 查询接口,用于高级搜寻 |
| 工作簿 | Sentinel 中的交互式仪表板,显示安全数据、趋势和运营指标的视图 |
| 监视列表 | Sentinel 中的参考数据表,用于为警报添加上下文,如 VIP 用户列表或批准的 IP 范围 |
| Fusion 检测 | 机器学习驱动的关联引擎,可自动检测跨数据源的多阶段攻击 |
工具与系统
- Microsoft Sentinel:基于 Azure Log Analytics 构建的云原生 SIEM/SOAR 平台,具有 AI 驱动的威胁检测功能
- Azure Logic Apps:低代码自动化平台,用于构建由 Sentinel 事件触发的 SOAR 剧本
- Microsoft 威胁情报:集成威胁源,提供 IP、域和 URL 指标,用于与安全日志进行匹配
- Azure Data Explorer:高性能分析引擎,为 Sentinel KQL 查询提供支持,用于大规模数据探索
- MITRE ATT&CK Navigator:用于将 Sentinel 检测规则映射到对手战术和技术的框架
常见场景
场景:检测跨云凭据窃取活动
上下文:攻击者通过网络钓鱼攻陷一个 Azure AD 账户,然后通过联合身份使用该账户访问 AWS 资源。Sentinel 需要将 Azure 登录异常与异常的 AWS API 活动关联起来。
方法:
- 创建检测 Azure AD 不可能旅行或异常登录风险的分析规则
- 编写一个 KQL 查询,将被攻陷的 Azure AD 身份与 AWS CloudTrail AssumeRoleWithSAML 事件关联
- 构建一个 Fusion 检测规则,将 Azure AD 风险事件与后续的 AWS 权限提升活动联系起来
- 部署一个 SOAR 剧本,自动禁用 Azure AD 账户并撤销 AWS STS 会话
- 创建一个工作簿,显示从初始攻陷到横向移动再到 AWS 的时间线
- 在数据湖中运行一个搜寻查询,检查是否有其他账户受到类似模式的影响
陷阱:未跨云提供商关联身份会遗漏完整的攻击链。将分析规则频率设置得过低(例如 24 小时)会使攻击者在数小时内未被发现。
输出格式
Microsoft Sentinel SOC Operations Report
==========================================
工作区: sentinel-workspace
数据源: 14 个连接器已激活
报告周期: 2025-02-01 至 2025-02-23
数据引入:
Azure AD 登录日志: 2.3 TB (23 天)
AWS CloudTrail: 1.8 TB (23 天)
Azure Activity: 0.9 TB (23 天)
Defender for Cloud 警报: 45 GB (23 天)
总引入量: 5.1 TB
检测摘要:
活跃分析规则: 87
已创建事件: 234
严重: 8 | 高: 34 | 中: 89 | 低: 103
平均检测时间 (MTTD): 4.2 分钟
平均响应时间 (MTTR): 18 分钟
主要事件类型:
检测到不可能旅行: 42 个事件
AWS 未授权 API 调用模式: 28 个事件
S3 中大规模文件删除: 3 个事件
可疑 Azure AD 应用注册: 12 个事件
自动化:
已执行剧本: 156
账户已自动禁用: 23
事件已自动丰富: 198
误报率: 12%