关于 security-alert-triage
用于调查 Elastic Security 告警、在案例中记录发现并确认告警的技能。它要求先收集上下文再分类,并区分证据与评估结论。
主要功能
- 01获取并分组未处理告警
- 02调查进程、网络及相关告警上下文
- 03收集证据后再分类
- 04创建案例并关联告警
- 05确认相关告警
适用场景
- 01端到端分诊一条未确认告警
- 02按主机和时间分组调查告警
- 03确认告警前将发现记录到案例
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elastic/ agent-skills --skill security-alert-triage安装后在 Claude Code 中输入/security-alert-triage确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/classification-guide.mdscripts/acknowledge-alert.jses-client.jsfetch-next-alert.jskibana-client.jsrun-query.js详细介绍
警报分流
逐条分析 Elastic Security 警报:收集上下文、分类、创建案例并确认。此技能依赖 case-management 技能来创建案例。
前提条件
首次使用前,请从 skills/security 目录安装依赖项:
cd skills/security && npm install
设置必需的环境变量(或将其添加到工作区根目录中的 .env 文件):
export ELASTICSEARCH_URL="https://your-cluster.es.cloud.example.com:443"
export ELASTICSEARCH_API_KEY="your-api-key"
export KIBANA_URL="https://your-cluster.kb.cloud.example.com:443"
export KIBANA_API_KEY="your-kibana-api-key"
快速开始
所有命令均从工作区根目录运行。始终遵循获取 → 调查 → 记录 → 确认的顺序。直接调用工具——不要先读取技能文件或浏览工作区。
node skills/security/alert-triage/scripts/fetch-next-alert.js
node skills/security/case-management/scripts/case-manager.js find --tags "agent_id:<id>"
node skills/security/alert-triage/scripts/run-query.js --query-file query.esql --type esql
node skills/security/case-management/scripts/case-manager.js create --title "..." --description "..." --tags "classification:..." "agent_id:<id>" --severity <level> --yes
node skills/security/case-management/scripts/case-manager.js attach-alert --case-id <id> --alert-id <id> --alert-index <index> --rule-id <uuid> --rule-name "<name>" --yes
node skills/security/alert-triage/scripts/acknowledge-alert.js --related --agent <id> --timestamp <ts> --window 60 --yes
常见多步骤工作流
| 任务 | 要调用的工具(按顺序) |
|---|---|
| 端到端分流 | fetch_next_alert → run_query(上下文)→ case_manager create(案例)→ acknowledge_alert |
| 收集上下文 | run_query(进程树、网络、相关警报) |
| 分类后创建案例 | case_manager create → case_manager attach-alert |
| 分流后确认 | acknowledge_alert(批量处理时使用 related 模式) |
务必完成整个工作流:获取 → 调查 → 记录 → 确认。不要在收集完上下文后就停止——确认前,先根据调查结果创建或更新案例。
关键执行规则:
- 立即开始执行工具——不要先读取 SKILL.md、浏览工作区或列出文件。
- 对于 ES|QL 查询,先将查询写入临时
.esql文件,再通过--query-file传入。不要使用edit_file——使用一次shell调用:echo "..." > query.esql && node ... --query-file query.esql。 - 集中收集上下文:运行 2-4 个有针对性的查询(进程树、网络、相关警报),不要运行 10 个以上。
- 只报告工具返回的内容。逐字复制标识符——不要改述 ID、时间戳或主机名。
关键原则
- 不要过早分类。 在作出无害/未知/恶意的判断前,收集所有上下文。
- 大多数警报都是误报,即使看起来很吓人也是如此。规则名称如 “Malicious Behavior” 或严重性为 “critical” 都不是证据。
- 证据不足时,选择 **“Unknown”(未知)**是可以接受的,而且往往是正确的。
- 判定为恶意需要有力的佐证:持久化 + C2、凭据窃取、横向移动——仅有可疑的 API 调用并不足够。
- 逐字报告工具输出。 按工具返回的内容准确复制 ID、主机名、时间戳和计数。不要取整数字、缩写 ID 或改述错误消息。
工作流
对多个警报进行分流时,先分组,再逐组分流:
- [ ] Step 0: Group alerts by agent/host and time window
- [ ] Step 1: Check existing cases
- [ ] Step 2: Gather full context (DO NOT SKIP)
- [ ] Step 3: Create or update case (only AFTER context gathered)
- [ ] Step 4: Acknowledge alert and all related alerts
- [ ] Step 5: Fetch next alert group and repeat
步骤 0:分流前对警报分组
当用户询问多个未处理警报时,先将它们分组,以避免重复调查:查询未处理警报,按 agent.id 分组,再按时间窗口细分(约 5 分钟 = 可能属于同一事件),并将每组作为一个整体进行分流。
使用 ES|QL 进行概览(使用 PowerShell 时先写入文件):
FROM .alerts-security.alerts-*
| WHERE kibana.alert.workflow_status == "open" AND @timestamp >= "<start>"
| STATS alert_count=COUNT(*), rules=VALUES(kibana.alert.rule.name) BY agent.id
| SORT alert_count DESC
完整的查询模板请参阅 references/classification-guide.md。
步骤 1:检查现有案例
创建新案例前,先检查此警报是否属于现有案例。使用 case-management 技能:
node skills/security/case-management/scripts/case-manager.js find --tags "agent_id:<agent_id>"
node skills/security/case-management/scripts/case-manager.js cases-for-alert --alert-id <alert_id>
查找具有相同 Agent ID、用户或相关检测规则,且时间窗口相近的案例。
注意:
find --search在 Serverless 上可能返回 500 错误。请改用find --tags或list。
步骤 2:收集上下文
这是最重要的一步。切勿跳过或走捷径。 在形成任何分类意见之前,必须完成所有子步骤。
时间范围警告: 告警可能已过去数天或数周。切勿使用 NOW() - 1 HOUR 这样的相对时间。提取告警的 @timestamp,并围绕该时间构建前后各 1 小时的查询。
子步骤: (2a) 同一 Agent/用户的相关告警;(2b) 规则在各环境中的触发频率(频率高 = 易产生误报);(2c) 实体上下文 — 进程树、网络、注册表、文件;(2d) 行为调查 — 持久化、C2、横向移动、凭据访问。
示例 — 进程树(使用带 KEEP 的 ES|QL;避免使用会产生 10K+ 行的 --full):
FROM logs-endpoint.events.process-*
| WHERE agent.id == "<agent_id>" AND @timestamp >= "<alert_time - 5min>" AND @timestamp <= "<alert_time + 10min>"
AND process.parent.name IS NOT NULL
AND process.name NOT IN ("svchost.exe", "conhost.exe", "agentbeat.exe")
| KEEP @timestamp, process.name, process.command_line, process.pid, process.parent.name, process.parent.pid
| SORT @timestamp | LIMIT 80
| 数据类型 | 索引模式 |
|---|---|
| 告警 | .alerts-security.alerts-* |
| 进程 | logs-endpoint.events.process-* |
| 网络 | logs-endpoint.events.network-* |
| 日志 | logs-* |
完整的查询模板和分类标准请参阅 references/classification-guide.md。
步骤 3:创建或更新案例
收集上下文后,创建案例并附加告警。使用 --rule-id 和 --rule-name(必填;缺少时会返回 400 错误):
node skills/security/case-management/scripts/case-manager.js create \
--title "<concise summary>" \
--description "<findings, IOCs, attack chain, MITRE techniques>" \
--tags "classification:<benign|unknown|malicious>" "confidence:<0-100>" "mitre:<technique>" "agent_id:<id>" \
--severity <low|medium|high|critical>
node skills/security/case-management/scripts/case-manager.js attach-alert \
--case-id <case_id> --alert-id <alert_id> --alert-index <index> \
--rule-id <rule_uuid> --rule-name "<rule name>"
# Multiple alerts: attach-alerts --alert-ids <id1> <id2>
# Add notes: add-comment --case-id <id> --comment "Findings..."
案例描述: 摘要(1-2 句话);攻击链;IOC(哈希、IP、路径);MITRE 技术;行为发现;响应上下文(补救措施、面临风险的凭据)。
步骤 4:确认告警
一并确认所有相关告警。先使用 --dry-run 确认范围,然后不带该参数运行:
# By host name — preferred when triaging a host
node skills/security/alert-triage/scripts/acknowledge-alert.js --query --host <hostname> --dry-run
node skills/security/alert-triage/scripts/acknowledge-alert.js --query --host <hostname> --yes
# By agent ID — preferred when agent.id is known
node skills/security/alert-triage/scripts/acknowledge-alert.js --related --agent <id> --timestamp <ts> --window 60 --dry-run
node skills/security/alert-triage/scripts/acknowledge-alert.js --related --agent <id> --timestamp <ts> --window 60 --yes
对于较长的攻击链,请增大 --window(例如,300 表示 5 分钟)。报告工具输出中确切的已确认告警数量。传入 --yes 跳过确认提示(由 Agent 调用时必需)。
步骤 5:重复
node skills/security/alert-triage/scripts/fetch-next-alert.js
工具参考
fetch-next-alert.js
获取最早的未确认 Elastic Security 告警。
node skills/security/alert-triage/scripts/fetch-next-alert.js [--days <n>] [--json] [--full] [--verbose]
run-query.js
针对 Elasticsearch 运行 KQL 或 ES|QL 查询。
PowerShell 警告:ES|QL 查询包含管道字符(|),PowerShell 会将其解释为 shell 管道。始终使用 --query-file 运行 ES|QL:
# Write query to file, then run
node skills/security/alert-triage/scripts/run-query.js --query-file query.esql --type esql
不含管道的 KQL 查询可以直接传入:
node skills/security/alert-triage/scripts/run-query.js "agent.id:<id>" --index "logs-*" --days 7
| 参数 | 描述 |
|---|---|
query | KQL 查询(位置参数) |
--query-file, -q | 从文件读取查询(PowerShell 上运行 ES|QL 时必需) |
--type, -t | kql 或 esql(默认:kql) |
--index, -i | 索引模式(默认:logs-*) |
--size, -s | 最大结果数(默认:100) |
--days, -d | 限制为最近 N 天 |
--json | 原始 JSON 输出 |
--full | 完整文档源 |
acknowledge-alert.js
通过将 workflow_status 更新为 acknowledged 来确认警报。
| 模式 | 命令 |
|---|---|
| 单条 | node skills/security/alert-triage/scripts/acknowledge-alert.js <alert_id> --index <index> --yes |
| 关联 | node skills/security/alert-triage/scripts/acknowledge-alert.js --related --agent <id> --timestamp <ts> [--window 60] --yes |
| 按主机 | node skills/security/alert-triage/scripts/acknowledge-alert.js --query --host <hostname> [--time-start <ts>] [--time-end <ts>] --yes |
| 查询 | node skills/security/alert-triage/scripts/acknowledge-alert.js --query --agent <id> [--time-start <ts>] [--time-end <ts>] --yes |
| 试运行 | 在任意模式下添加 --dry-run(无需确认) |
| 确认 | 所有写入模式都会提示确认;传入 --yes 可跳过 |
示例
- “获取下一条未确认的警报并进行分类处理”
- “调查警报 ID abc-123——收集上下文、进行分类,如果属于恶意警报则创建案例”
- “处理过去 24 小时内最严重的 5 条警报”
指南
- 仅报告工具输出——不要编造工具响应中没有的 ID、主机名、IP 地址或详细信息。
- 保留请求中的标识符——在工具调用和响应中使用用户提供的确切值。
- 根据工具返回的数据简洁地确认操作。
- 区分事实和推断——将超出工具输出的结论标记为你的评估。
生产环境使用
- 所有写入操作(
acknowledge-alert.js)都会提示确认。由 Agent 调用时,传入--yes或-y可跳过确认。 - 批量确认前使用
--dry-run预览范围,不修改数据。 - 确认脚本使用 Kibana Detection Engine API,兼容自行管理和 Serverless 部署。
- 运行任何脚本前,确认环境变量指向预期集群——确认操作无法撤销。
环境变量
| 变量 | 必填 | 说明 |
|---|---|---|
ELASTICSEARCH_URL | 是 | Elasticsearch URL |
ELASTICSEARCH_API_KEY | 是 | Elasticsearch API 密钥 |
KIBANA_URL | 是 | Kibana URL(用于案例管理) |
KIBANA_API_KEY | 是 | Kibana API 密钥(用于案例管理) |