调优和重构 Google Chronicle Curated Detections,以消除告警疲劳并修复逻辑缺口/缺陷。
本仓库记录了针对原生 Google SecOps(Chronicle)精选检测规则的架构设计缺陷、逻辑差异及调优策略。
尽管 Google Threat Intelligence(GTIG)提供了卓越的概念性威胁覆盖(例如追踪 APT29/BRICKSTORM 活动),但精选规则的原始 YARA-L 实现有时会因实现层面的疏忽而出现问题,例如分组逻辑矛盾和硬编码阈值变量。在真实的企业环境中,这经常导致大量告警疲劳。
本项目分析了原生规则为何会失效或在 SOC 中泛滥,并分享了优化后的自定义规则和补丁以解决这些问题。
Google 发布了一套规则,用于检测被入侵的服务主体从 Microsoft 365 Exchange Online 进行的大规模电子邮件窃取(APT29/Midnight Blizzard 大量使用的技术)。
受影响的精选规则包括:
O365 Mailbox Access by Service Principal with Multiple User AgentsO365 Multiple Mailboxes Accessed by Service PrincipalO365 Mailbox Access by Service Principal from Multiple ASNsO365 Multiple Mailboxes Accessed via Microsoft Graph API这套规则在既定目标与 YARA-L 实现之间存在系统性的逻辑不匹配,很可能是由于规则包中的代码复用所致。这些规则未能正确区分自动化服务主体与标准人类活动,导致在正常员工行为上触发告警。
尽管规则描述明确写道:“检测具有单一 O365 会话 ID 的服务主体……”,但“Multiple User Agents”规则的 YARA-L match 部分却按 $application_id 而非会话 ID($session_id)进行分组。这完全违背了规则所述的目标。
这些规则会跟踪与特定 ClientAppId 关联的异常行为模式(如 IP、ASN 或 User-Agent 的变化)。尽管 Google 为多个 Microsoft 原生应用程序加入了排除正则表达式,却令人费解地遗漏了最普遍的人类移动客户端:Microsoft Outlook 移动应用(27922004-5251-4030-b22d-91ecd9a37ea4)。
Multiple ASNs 告警。不同员工使用 iOS 和 Android 设备查看同一个部门邮箱时,则会触发 Multiple User Agents 告警。为了识别后端服务账户,Google 的逻辑依赖以下条件:
$e.principal.user.userid != $e.target.user.userid
[email protected])也是标准行为。这一设计缺陷会在正常的运营人员流量上产生大量噪声。要修复这些设计缺陷,你可以根据运营需求选择两种方案:
方案 1:原生 SIEM 排除(快速修复)
你不一定需要禁用规则或编写自定义代码。你可以直接在 Google SecOps SIEM UI 中创建一个排除项。只需添加一个针对 Outlook Mobile(27922004-5251-4030-b22d-91ecd9a37ea4)以及你授权的备份应用程序(例如 Keepit)的 ClientAppId 的排除项。这会立即阻止误报洪流,同时保持 Google 精选规则处于启用状态。
方案 2:部署自定义规则(架构性修复)
如果你想彻底修复底层的分组逻辑缺陷(例如 $application_id 不匹配),则必须禁用精选检测并部署自定义规则。修复内容包括:
27922004-...)加入白名单。match 部分,以便按会话正确聚合。rule custom_ttp_o365_mailbox_access_by_service_principal_with_multiple_uas {
meta:
rule_name = "[CUSTOM] O365 Mailbox Access by Service Principal with Multiple User Agents"
description = "Detects a Service Principal with a single O365 session ID accessing O365 mailboxes with multiple user agents. Tuned to fix grouping logic and exclude Outlook Mobile (Public Client) human traffic."
severity = "Low"
tactic = "TA0009"
technique = "T1114.002"
events:
$e.metadata.log_type = "OFFICE_365"
$e.metadata.product_event_type = "MailItemsAccessed" nocase
$e.target.application = "Exchange"
$e.security_result.detection_fields["RecordType"] = /^(2|50)$/
// Extract actual Session ID and App ID
$session_id =$e.network.session_id
$application_id =$e.additional.fields["ClientAppId"]
$e.principal.user.userid !=$e.target.user.userid
(
$e.network.http.user_agent = /AppId/ nocase or$e.additional.fields["ClientAppId"] = /./
)
// EXCLUSIONS: Added Outlook Mobile + Standard Google Exclusions
$e.additional.fields["ClientAppId"] != /^(27922004-5251-4030-b22d-91ecd9a37ea4|bea75f7a-2505-46e8-9bf6-d3f7da9c9da7|b52893c8-bc2e-47fc-918b-77022b299bbc|...)$/ nocase
match:
// Group by both App AND Session to isolate the specific token lifecycle
$application_id,$session_id over 3h
outcome:
$vendor_name = "Microsoft"
$product_name = "Office 365"
$source_ua_dc = count_distinct($e.network.http.user_agent)
$client_app_id = array_distinct($e.additional.fields["ClientAppId"])
condition:
// Triggers if the SAME session rotates 2+ User Agents
$e and $source_ua_dc >= 2
}
(逻辑相同,但在排除项中确保将你授权的备份解决方案(如 Keepit(a7cd46df...))与 Outlook Mobile 一起加入白名单。)
(与 User Agents 规则不同,Google 在这条规则中实际上正确地按 $session_id 进行了分组。然而,它仍然缺少 Outlook Mobile 排除项。请遵循与上述相同的排除逻辑,保留 $source_asn_dc >= 2 这一条件。)
(逻辑相同。确保将授权的备份应用程序(如 Keepit(a7cd46df...))追加到 events 块末尾的排除正则表达式中。)
规则: ttp_o365_teams_external_impersonation_attempt
目标事件: OFFICE_365(metadata.product_event_type = "TeamsImpersonationDetected")
Microsoft Defender for Office 365 会检查外部入站 Microsoft Teams 聊天,并通过 TeamsImpersonationDetected 审计操作标记潜在的域名或品牌冒充行为。当转换为 YARA-L 检测规则时,原生精选实现存在实体归属错误和匹配键疏漏的问题。
// Native Flawed Implementation Sample
events:
$e.metadata.log_type = "OFFICE_365"
$e.metadata.product_event_type = /TeamsImpersonationDetected/ nocase
$principal_userid =$e.principal.user.userid
match:
$principal_userid over 1h
outcome:
$result = "succeeded"
$adversary_name = array_distinct($e.principal.user.userid)
Chronicle 的默认解析器会将收件人 UserId(接收消息的内部用户)映射到 principal.user.userid。而试图进行冒充的外部行为者则位于嵌套的 Sender 对象中(Sender.UPN),被解析到 additional.fields["Sender_UPN"]。
$adversary_name = array_distinct($e.principal.user.userid),该规则在下游 SOC 告警和 SOAR 案例中将内部受害者标记为对手。该规则强制执行 match: $principal_userid over 1h,按收件员工对告警进行分组。
选项 1:告警配置文件调整(快速修复)
一种直接的操作修复方式是,针对此精选检测禁用 Broad 规则集的告警,并严格保持 Precise 通道启用。这样无需部署自定义规则,即可防止良性的跨租户或未经确认的冒充事件淹没分析师队列。
选项 2:部署自定义规则(架构修复)
此自定义规则保持原始架构不变,仅修改发送者提取、匹配分组键和对手结果字段:
rule custom_ttp_o365_teams_external_impersonation_attempt {
meta:
rule_name = "[CUSTOM] O365 Teams External Impersonation Attempt"
description = "This event is logged whenever Office 365 Teams an external message sender is detected to have potential impersonation activity. Tuned to group and attribute alerts by the external sender."
severity = "Medium"
tactic = "TA0001"
technique = "T1566"
events:
$e.metadata.log_type = "OFFICE_365"
$e.metadata.product_event_type = /TeamsImpersonationDetected/ nocase
$sender_upn =$e.additional.fields["Sender_UPN"]
match:
$sender_upn over 1h
outcome:
$vendor_name = "Microsoft"
$product_name = "Office 365"
$result = "succeeded"
$event_count = count_distinct($e.metadata.id)$risk_score = 50
$adversary_name = array_distinct($sender_upn)
$result_time = min($e.metadata.event_timestamp.seconds)
condition:
$e
}
规则: Anomalous Auth Attempts Total by Principal Hostname and Target User ID
(注:UEBA 代表“用户与实体行为分析”。这些规则不使用静态签名,而是依赖数学算法对“正常”行为建立基线,并对统计偏差发出告警。)
此 UEBA 规则试图通过计算 30 天内的历史平均值和标准差来检测异常的认证峰值。