
本动手实践教程演示如何使用 Elasticsearch 查询语言(ES|QL)执行高级威胁狩猎技术。
在一个模拟的高级持续性威胁(APT)攻击活动中,我们分析身份验证、进程执行和网络遥测数据中的安全事件,以检测:
-
通过恶意电子邮件附件进行的初始入侵
-
通过网络进行的横向移动
-
权限提升尝试
-
数据外泄活动
ES|QL 支持强大的转换、过滤、数据丰富和统计分析功能,非常适合复杂的安全调查。本教程提供了使用 ES|QL 进行威胁狩猎的实际示例,从识别可疑用户行为到构建攻击时间线。
要求
你需要一个正在运行的 Elasticsearch 集群 以及 Kibana 才能运行本教程。有关部署选项,请参阅部署类型选择文档。
如何运行 ES|QL 查询
在本教程中,ES|QL 示例以下面的格式显示:
vbnet
`
1. FROM windows-security-logs
2. | WHERE event.code == "4624"
3. | LIMIT 1000
`Lobster AI
你可以使用以下方式运行这些查询:
-
交互式界面:
-
Timeline。在导航菜单中查找 Timeline,或者使用全局搜索字段。
-
Discover。在导航菜单中查找 Discover,或者使用全局搜索字段。
-
-
通过 Dev Tools Console 使用 REST API。此方式需要额外的格式:
查看 ES|QL 的 Console 语法
python
`
1. POST /_query?format=txt
2. {
3. "query": """
4. FROM windows-security-logs
5. | WHERE event.code == "4624"
6. | LIMIT 1000
7. """
8. }
`Lobster AI
步骤 0:添加示例数据
要跟随本教程进行操作,你需要使用 Dev Tools Console 向集群添加示例数据。
总体来说,数据分为两种类型:
-
核心索引:这些是包含你要分析的日志和事件的主要安全索引。我们需要三个核心索引:
windows-security-logs、process-logs和network-logs。 -
查找索引:这些是为核心数据提供额外上下文的辅助索引。我们需要三个查找索引:
asset-inventory、user-context和threat-intel。
创建核心索引
首先,为我们的威胁狩猎场景创建核心安全索引:
bash
`
1. PUT /windows-security-logs
2. {
3. "mappings": {
4. "properties": {
5. "@timestamp": {"type": "date"},
6. "event": {
7. "properties": {
8. "code": {"type": "keyword"}, # Event codes like 4624 (successful logon) and 4625 (failed logon) are stored as keywords for exact matching.
9. "action": {"type": "keyword"}
10. }
11. },
12. "user": {
13. "properties": {
14. "name": {"type": "keyword"},
15. "domain": {"type": "keyword"}
16. }
17. },
18. "host": {
19. "properties": {
20. "name": {"type": "keyword"},
21. "ip": {"type": "ip"}
22. }
23. },
24. "source": {
25. "properties": {
26. "ip": {"type": "ip"}
27. }
28. },
29. "logon": {
30. "properties": {
31. "type": {"type": "keyword"}
32. }
33. }
34. }
35. }
36. }
`Lobster AI
事件代码(例如 4624(登录成功)和 4625(登录失败))以 keyword 类型存储,以便进行精确匹配。
现在,让我们向 windows-security-logs 索引添加一些身份验证事件示例数据,也就是登录失败和登录成功事件。
bash
`
1. POST /_bulk?refresh=wait_for
2. {"index":{"_index":"windows-security-logs"}}
3. {"@timestamp":"2025-05-20T08:15:00Z","event":{"code":"4625","action":"logon_failed"},"user":{"name":"jsmith","domain":"corp"},"host":{"name":"WS-001","ip":"10.1.1.50"},"source":{"ip":"10.1.1.100"}}
4. {"index":{"_index":"windows-security-logs"}}
5. {"@timestamp":"2025-05-20T08:17:00Z","event":{"code":"4624","action":"logon_success"},"user":{"name":"jsmith","domain":"corp"},"host":{"name":"WS-001","ip":"10.1.1.50"},"source":{"ip":"10.1.1.100"},"logon":{"type":"3"}}
6. {"index":{"_index":"windows-security-logs"}}
7. {"@timestamp":"2025-05-20T09:30:00Z","event":{"code":"4624","action":"logon_success"},"user":{"name":"jsmith","domain":"corp"},"host":{"name":"SRV-001","ip":"10.1.2.10"},"source":{"ip":"10.1.1.50"},"logon":{"type":"3"}}
8. {"index":{"_index":"windows-security-logs"}}
9. {"@timestamp":"2025-05-20T10:45:00Z","event":{"code":"4624","action":"logon_success"},"user":{"name":"jsmith","domain":"corp"},"host":{"name":"DB-001","ip":"10.1.3.5"},"source":{"ip":"10.1.2.10"},"logon":{"type":"3"}}
10. {"index":{"_index":"windows-security-logs"}}
11. {"@timestamp":"2025-05-20T02:30:00Z","event":{"code":"4624","action":"logon_success"},"user":{"name":"admin","domain":"corp"},"host":{"name":"DC-001","ip":"10.1.4.10"},"source":{"ip":"10.1.3.5"},"logon":{"type":"3"}}
`Lobster AI
接下来,创建一个用于进程执行日志的索引。
bash
`
1. PUT /process-logs
2. {
3. "mappings": {
4. "properties": {
5. "@timestamp": {"type": "date"},
6. "process": {
7. "properties": {
8. "name": {"type": "keyword"},
9. "command_line": {"type": "text"}, # Command lines are stored as text fields to enable full-text search for suspicious parameters and encoded commands.
10. "parent": {
11. "properties": {
12. "name": {"type": "keyword"}
13. }
14. }
15. }
16. },
17. "user": {
18. "properties": {
19. "name": {"type": "keyword"}
20. }
21. },
22. "host": {
23. "properties": {
24. "name": {"type": "keyword"}
25. }
26. }
27. }
28. }
29. }
`Lobster AI
命令行以 text 字段存储,以支持针对可疑参数和编码命令的全文搜索。
向 process-logs 索引添加一些示例数据。
swift
`
1. POST /_bulk?refresh=wait_for
2. {"index":{"_index":"process-logs"}}
3. {"@timestamp":"2025-05-20T08:20:00Z","process":{"name":"powershell.exe","command_line":"powershell.exe -enc JABzAD0ATgBlAHcALgBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAA=","parent":{"name":"winword.exe"}},"user":{"name":"jsmith"},"host":{"name":"WS-001"}}
4. {"index":{"_index":"process-logs"}}
5. {"@timestamp":"2025-05-20T09:35:00Z","process":{"name":"net.exe","command_line":"net user /domain","parent":{"name":"cmd.exe"}},"user":{"name":"jsmith"},"host":{"name":"SRV-001"}}
6. {"index":{"_index":"process-logs"}}
7. {"@timestamp":"2025-05-20T10:50:00Z","process":{"name":"sqlcmd.exe","command_line":"sqlcmd -S localhost -Q \"SELECT * FROM customers\"","parent":{"name":"powershell.exe"}},"user":{"name":"jsmith"},"host":{"name":"DB-001"}}
8. {"index":{"_index":"process-logs"}}
9. {"@timestamp":"2025-05-20T02:35:00Z","process":{"name":"ntdsutil.exe","command_line":"ntdsutil \"ac i ntds\" \"ifm\" \"create full c:\\temp\\ntds\"","parent":{"name":"cmd.exe"}},"user":{"name":"admin"},"host":{"name":"DC-001"}}
10. {"index":{"_index":"process-logs"}}
11. {"@timestamp":"2025-05-20T12:15:00Z","process":{"name":"schtasks.exe","command_line":"schtasks.exe /create /tn UpdateCheck /tr c:\\windows\\temp\\update.exe /sc daily","parent":{"name":"cmd.exe"}},"user":{"name":"jsmith"},"host":{"name":"WS-001"}}
12. {"index":{"_index":"process-logs"}}
13. {"@timestamp":"2025-05-20T12:30:00Z","process":{"name":"schtasks.exe","command_line":"schtasks.exe /create /tn SystemManager /tr powershell.exe -enc ZQBjAGgAbwAgACIASABlAGwAbABvACIA /sc minute /mo 5","parent":{"name":"powershell.exe"}},"user":{"name":"jsmith"},"host":{"name":"SRV-001"}}
14. {"index":{"_index":"process-logs"}}
15. {"@timestamp":"2025-05-20T13:15:00Z","process":{"name":"sc.exe","command_line":"sc.exe create RemoteService binPath= c:\\windows\\temp\\remote.exe","parent":{"name":"cmd.exe"}},"user":{"name":"jsmith"},"host":{"name":"DB-001"}}
16. {"index":{"_index":"process-logs"}}
17. {"@timestamp":"2025-05-20T13:20:00Z","process":{"name":"sc.exe","command_line":"sc.exe create BackdoorService binPath= c:\\programdata\\svc.exe","parent":{"name":"powershell.exe"}},"user":{"name":"jsmith"},"host":{"name":"SRV-001"}}
18. {"index":{"_index":"process-logs"}}
19. {"@timestamp":"2025-05-20T13:25:00Z","process":{"name":"sc.exe","command_line":"sc.exe create PersistenceService binPath= c:\\windows\\system32\\malicious.exe","parent":{"name":"cmd.exe"}},"user":{"name":"admin"},"host":{"name":"DC-001"}}
`Lobster AI
接下来,创建一个用于网络流量日志的索引。
bash
`
1. PUT /network-logs
2. {
3. "mappings": {
4. "properties": {
5. "@timestamp": {"type": "date"},
6. "source": {
7. "properties": {
8. "ip": {"type": "ip"},
9. "port": {"type": "integer"}
10. }
11. },
12. "destination": {
13. "properties": {
14. "ip": {"type": "ip"},
15. "port": {"type": "integer"}
16. }
17. },
18. "network": {
19. "properties": {
20. "bytes": {"type": "long"},
21. "protocol": {"type": "keyword"}
22. }
23. },
24. "host": {
25. "properties": {
26. "name": {"type": "keyword"}
27. }
28. }
29. }
30. }
31. }
`Lobster AI
向 network-logs 索引添加一些示例数据。
bash
`
1. POST /_bulk?refresh=wait_for
2. {"index":{"_index":"network-logs"}}
3. {"@timestamp":"2025-05-20T08:25:00Z","source":{"ip":"10.1.1.50","port":52341},"destination":{"ip":"185.220.101.45","port":443},"network":{"bytes":2048,"protocol":"tcp"},"host":{"name":"WS-001"}}
4. {"index":{"_index":"network-logs"}}
5. {"@timestamp":"2025-05-20T11:15:00Z","source":{"ip":"10.1.3.5","port":54892},"destination":{"ip":"185.220.101.45","port":443},"network":{"bytes":50000000,"protocol":"tcp"},"host":{"name":"DB-001"}}
6. {"index":{"_index":"network-logs"}}
7. {"@timestamp":"2025-05-20T02:40:00Z","source":{"ip":"10.1.4.10","port":61234},"destination":{"ip":"185.220.101.45","port":443},"network":{"bytes":500000000,"protocol":"tcp"},"host":{"name":"DC-001"}}
`Lobster AI
创建查找索引
查找模式允许这些索引与 LOOKUP JOIN 操作一起使用,从而使用资产上下文丰富安全事件。
使用 lookup 索引模式创建我们需要的索引。
bash
`
1. PUT /asset-inventory
2. {
3. "mappings": {
4. "properties": {
5. "host.name": {"type": "keyword"},
6. "asset.criticality": {"type": "keyword"},
7. "asset.owner": {"type": "keyword"},
8. "asset.department": {"type": "keyword"}
9. }
10. },
11. "settings": {
12. "index.mode": "lookup"
13. }
14. }
`Lobster AI
bash
`
1. PUT /user-context
2. {
3. "mappings": {
4. "properties": {
5. "user.name": {"type": "keyword"},
6. "user.role": {"type": "keyword"},
7. "user.department": {"type": "keyword"},
8. "user.privileged": {"type": "boolean"}
9. }
10. },
11. "settings": {
12. "index.mode": "lookup"
13. }
14. }
`Lobster AI
bash
`
1. PUT /threat-intel
2. {
3. "mappings": {
4. "properties": {
5. "indicator.value": {"type": "keyword"},
6. "indicator.type": {"type": "keyword"},
7. "threat.name": {"type": "keyword"},
8. "threat.severity": {"type": "keyword"}
9. }
10. },
11. "settings": {
12. "index.mode": "lookup"
13. }
14. }
`Lobster AI
现在,我们可以使用上下文数据填充查找索引。这个单独的批量操作可以通过一次请求,将数据分别写入 user-context、threat-intel 和 asset-inventory 索引。
bash
`
1. POST /_bulk?refresh=wait_for
2. {"index":{"_index":"asset-inventory"}}
3. {"host.name":"WS-001","asset.criticality":"medium","asset.owner":"IT","asset.department":"finance"}
4. {"index":{"_index":"asset-inventory"}}
5. {"host.name":"SRV-001","asset.criticality":"high","asset.owner":"IT","asset.department":"operations"}
6. {"index":{"_index":"asset-inventory"}}
7. {"host.name":"DB-001","asset.criticality":"critical","asset.owner":"DBA","asset.department":"finance"}
8. {"index":{"_index":"asset-inventory"}}
9. {"host.name":"DC-001","asset.criticality":"critical","asset.owner":"IT","asset.department":"infrastructure"}
10. {"index":{"_index":"user-context"}}
11. {"user.name":"jsmith","user.role":"analyst","user.department":"finance","user.privileged":false}
12. {"index":{"_index":"user-context"}}
13. {"user.name":"admin","user.role":"administrator","user.department":"IT","user.privileged":true}
14. {"index":{"_index":"threat-intel"}}
15. {"indicator.value":"185.220.101.45","indicator.type":"ip","threat.name":"APT-29","threat.severity":"high"}
16. {"index":{"_index":"threat-intel"}}
17. {"indicator.value":"powershell.exe","indicator.type":"process","threat.name":"Living off the Land","threat.severity":"medium"}
`Lobster AI
步骤 1:狩猎初始入侵指标
我们的威胁狩猎第一阶段关注识别初始入侵。我们希望搜索来自 Office 应用程序的可疑 PowerShell 执行,这是常见的初始攻击向量。
ini
`
1. FROM process-logs
2. | WHERE process.name == "powershell.exe" AND process.parent.name LIKE "*word*" #1
3. | LOOKUP JOIN asset-inventory ON host.name #2
4. | LOOKUP JOIN user-context ON user.name #3
5. | EVAL encoded_command = CASE(process.command_line LIKE "*-enc*", true, false) #4
6. | WHERE encoded_command == true #5
7. | STATS count = COUNT(*) BY host.name, user.name, asset.criticality #6
8. | LIMIT 1000
`Lobster AI
-
使用
[WHERE](https://www.elastic.co/docs/reference/query-languages/esql/commands/where "WHERE")、[==](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/operators#esql-equals "==")和[LIKE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/operators#esql-like "LIKE")运算符检测 PowerShell 进程。 -
使用
[LOOKUP JOIN](https://www.elastic.co/docs/reference/query-languages/esql/commands/lookup-join "LOOKUP JOIN")与资产清单进行数据丰富。 -
使用
LOOKUP JOIN添加用户上下文。 -
使用
[EVAL](https://www.elastic.co/docs/reference/query-languages/esql/commands/eval "EVAL")和[CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE")检测编码命令。 -
使用
[WHERE](https://www.elastic.co/docs/reference/query-languages/esql/commands/where "WHERE")进行额外过滤。 -
使用
[STATS](https://www.elastic.co/docs/reference/query-languages/esql/commands/stats-by "STATS")和[COUNT](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/aggregation-functions/count "COUNT")按多个字段对结果进行聚合。
响应
响应包含可疑 PowerShell 执行的摘要,包括主机名称、用户名和资产关键性。
| count | host.name | user.name | asset.criticality |
|---|---|---|---|
| 1 | WS-001 | jsmith | medium |
步骤 2:检测横向移动模式
在此步骤中,我们跟踪用户在多个系统上的身份验证情况。这对于识别横向移动和潜在的权限提升非常重要。
此查询演示了 [DATE_TRUNC](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions/date_trunc "DATE_TRUNC") 如何创建时间窗口来进行速度分析,并结合 [COUNT_DISTINCT](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/aggregation-functions/count_distinct "COUNT_DISTINCT") 聚合和 [DATE_DIFF](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions/date_diff "DATE_DIFF") 计算,同时衡量用户在网络资产之间移动的范围和速度。
less
`
1. FROM windows-security-logs
2. | WHERE event.code == "4624" AND logon.type == "3"
3. | LOOKUP JOIN asset-inventory ON host.name
4. | EVAL time_bucket = DATE_TRUNC(30 minute, @timestamp)
5. | STATS unique_hosts = COUNT_DISTINCT(host.name),
6. criticality_levels = COUNT_DISTINCT(asset.criticality),
7. active_periods = COUNT_DISTINCT(time_bucket),
8. first_login = MIN(@timestamp),
9. last_login = MAX(@timestamp)
10. BY user.name
11. | WHERE unique_hosts > 2
12. | EVAL time_span_hours = DATE_DIFF("hour", first_login, last_login)
13. | EVAL movement_velocity = ROUND(unique_hosts / (time_span_hours + 1), 2)
14. | EVAL lateral_movement_score = unique_hosts * criticality_levels
15. | SORT lateral_movement_score DESC
16. | LIMIT 1000
`Lobster AI
-
使用
WHERE进行基本的身份验证过滤。 -
使用
DATE_TRUNC创建时间桶,以进行时间类型分析。 -
使用
STATS和COUNT_DISTINCT计算全面的访问指标。 -
使用
DATE_DIFF计算持续时间。 -
使用
EVAL和CASE进行风险评分。
响应
响应显示登录到多个主机的用户、这些主机的关键性级别以及其横向移动速度。
| unique_hosts | criticality_levels | active_periods | first_login | last_login | user.name | time_span_hours | movement_velocity | lateral_movement_score |
|---|---|---|---|---|---|---|---|---|
| 3 | 3 | 3 | 2025-05-20T08:17:00.000Z | 2025-05-20T10:45:00.000Z | jsmith | 2 | 1 | 9 |
步骤 3: 识别数据 访问和潜在的数据外泄
高级攻击者通常会将敏感数据作为目标。我们希望狩猎数据库访问行为,以及向外部系统进行的大规模数据传输。
less
`
1. FROM network-logs
2. | WHERE NOT CIDR_MATCH(destination.ip, "10.0.0.0/8", "192.168.0.0/16") #1
3. | EVAL indicator.value = TO_STRING(destination.ip) #2
4. | LOOKUP JOIN threat-intel ON indicator.value
5. | LOOKUP JOIN asset-inventory ON host.name
6. | WHERE threat.name IS NOT NULL
7. | STATS total_bytes = SUM(network.bytes),
8. connection_count = COUNT(*),
9. time_span = DATE_DIFF("hour", MIN(@timestamp), MAX(@timestamp)) #3
10. BY host.name, destination.ip, threat.name, asset.criticality
11. | EVAL mb_transferred = ROUND(total_bytes / 1048576, 2) #4
12. | EVAL risk_score = CASE(
13. asset.criticality == "critical" AND mb_transferred > 100, 10,
14. asset.criticality == "high" AND mb_transferred > 100, 7,
15. mb_transferred > 50, 5,
16. 3
17. ) #5
18. | WHERE total_bytes > 1000000
19. | SORT risk_score DESC, total_bytes DESC
20. | LIMIT 1000
`Lobster AI
-
使用
[CIDR_MATCH](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/ip-functions/cidr_match "CIDR_MATCH")过滤内部 IP 范围,以检测外部数据传输。 -
使用
[TO_STRING](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/type-conversion-functions/to_string "TO_STRING")统一 IP 格式,以便执行威胁情报查找。 -
使用
[DATE_DIFF](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions/date_diff "DATE_DIFF"),结合SUM和COUNT,衡量一段时间内的数据传输量。 -
使用
[ROUND](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/math-functions/round "ROUND")生成便于人类阅读的数值。 -
使用
[CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE")根据资产关键性和传输数据量进行风险评分。
响应
响应显示外部数据传输、其风险评分以及传输的数据量。
| total_bytes | connection_count | time_span | host.name | destination.ip | threat.name | asset.criticality | mb_transferred | risk_score |
|---|---|---|---|---|---|---|---|---|
| 500000000 | 1 | 0 | DC-001 | 185.220.101.45 | APT-29 | critical | 476 | 10 |
| 50000000 | 1 | 0 | DB-001 | 185.220.101.45 | APT-29 | critical | 47 | 3 |
步骤 4:构建攻击时间线并评估影响
为了了解攻击的推进过程,我们需要跨多个索引构建事件时间线。这有助于我们关联各种行为,并识别攻击者在环境中的驻留时间。
sql
`
1. FROM windows-security-logs, process-logs, network-logs # 1
2. | LOOKUP JOIN asset-inventory ON host.name
3. | LOOKUP JOIN user-context ON user.name
4. | WHERE user.name == "jsmith" OR user.name == "admin"
5. | EVAL event_type = CASE(
6. event.code IS NOT NULL, "Authentication",
7. process.name IS NOT NULL, "Process Execution",
8. destination.ip IS NOT NULL, "Network Activity",
9. "Unknown") # 2
10. | EVAL dest_ip = TO_STRING(destination.ip)
11. | EVAL attack_stage = CASE(
12. process.parent.name LIKE "*word*", "Initial Compromise",
13. process.name IN ("net.exe", "nltest.exe"), "Reconnaissance",
14. event.code == "4624" AND logon.type == "3", "Lateral Movement",
15. process.name IN ("sqlcmd.exe", "ntdsutil.exe"), "Data Access",
16. dest_ip NOT LIKE "10.*", "Exfiltration",
17. "Other") # 3
18. | SORT @timestamp ASC #4
19. | KEEP @timestamp, event_type, attack_stage, host.name, asset.criticality, user.name, process.name, destination.ip
20. | LIMIT 1000
`Lobster AI
-
使用
FROM同时读取多个索引,以进行全面的数据关联。 -
使用
[IS NOT NULL](https://www.elastic.co/docs/reference/query-languages/esql/commands/processing-commands#null-predicates "IS NOT NULL")和[CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE"),根据不同数据源对事件类型进行分类。 -
使用复杂的
[CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE")逻辑将事件映射到 MITRE ATT&CK 阶段。 -
使用
[SORT](https://www.elastic.co/docs/reference/query-languages/esql/commands/sort "SORT")构建按时间顺序排列的攻击时间线。
响应
响应提供按时间顺序排列的事件时间线,展示攻击者的行为以及对组织造成的影响。
| @timestamp | event_type | attack_stage | host.name | asset.criticality | user.name | process.name | destination.ip |
|---|---|---|---|---|---|---|---|
| 2025-05-20T02:30:00.000Z | 身份验证 | 横向移动 | DC-001 | critical | admin | null | null |
| 2025-05-20T02:35:00.000Z | 进程执行 | 数据访问 | DC-001 | critical | admin | ntdsutil.exe | null |
| 2025-05-20T08:15:00.000Z | 身份验证 | 其他 | WS-001 | medium | jsmith | null | null |
| 2025-05-20T08:17:00.000Z | 身份验证 | 横向移动 | WS-001 | medium | jsmith | null | null |
| 2025-05-20T08:20:00.000Z | 进程执行 | 初始入侵 | WS-001 | medium | jsmith | powershell.exe | null |
| 2025-05-20T09:30:00.000Z | 身份验证 | 横向移动 | SRV-001 | high | jsmith | null | null |
| 2025-05-20T09:35:00.000Z | 进程执行 | 侦察 | SRV-001 | high | jsmith | net.exe | null |
| 2025-05-20T10:45:00.000Z | 身份验证 | 横向移动 | DB-001 | critical | jsmith | null | null |
| 2025-05-20T10:50:00.000Z | 进程执行 | 数据访问 | DB-001 | critical | jsmith | sqlcmd.exe | null |
| 2025-05-20T12:15:00.000Z | 进程执行 | 其他 | WS-001 | medium | jsmith | schtasks.exe | null |
| 2025-05-20T12:30:00.000Z | 进程执行 | 其他 | SRV-001 | high | jsmith | schtasks.exe | null |
| 2025-05-20T13:15:00.000Z | 进程执行 | 其他 | DB-001 | critical | jsmith | sc.exe | null |
| 2025-05-20T13:20:00.000Z | 进程执行 | 其他 | SRV-001 | high | jsmith | sc.exe | null |
| 2025-05-20T13:25:00.000Z | 进程执行 | 其他 | DC-001 | critical | admin | sc.exe | null |
步骤 5:狩猎异常的 解释器 使用行为
此查询演示了如何使用 ES|QL 的 [COUNT_DISTINCT](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/aggregation-functions/count_distinct "COUNT_DISTINCT") 函数和条件 [CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE") 语句,以用户和部门为维度建立解释器使用行为基线,并利用聚合函数识别异常脚本执行,这类行为可能表明账户已遭入侵或存在内部威胁。
sql
`
1. FROM process-logs
2. | WHERE process.name IN ("powershell.exe", "cmd.exe", "net.exe", "sqlcmd.exe", "schtasks.exe", "sc.exe")
3. | LOOKUP JOIN asset-inventory ON host.name
4. | LOOKUP JOIN user-context ON user.name
5. | STATS executions = COUNT(*),
6. unique_hosts = COUNT_DISTINCT(host.name),
7. unique_commands = COUNT_DISTINCT(process.name)
8. BY user.name, user.department
9. | WHERE executions > 1
10. | EVAL usage_pattern = CASE(
11. executions > 5, "High Usage",
12. executions > 3, "Moderate Usage",
13. "Low Usage"
14. )
15. | SORT executions DESC
16. | LIMIT 1000
`Lobster AI
-
使用
WHERE...IN监控高风险系统工具。 -
使用
[LOOKUP JOIN](https://www.elastic.co/docs/reference/query-languages/esql/commands/lookup-join "LOOKUP JOIN")与asset-inventory和user-context索引结合,为事件添加上下文。 -
使用
[COUNT_DISTINCT](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/aggregation-functions/count_distinct "COUNT_DISTINCT")衡量可疑工具使用的广度。 -
使用
[CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE")对使用模式进行分类,以便进行异常检测。
响应
响应显示每个用户和部门的执行次数、唯一主机数量以及使用模式。
| executions | unique_hosts | unique_commands | user.name | user.department | usage_pattern |
|---|---|---|---|---|---|
| 7 | 3 | 5 | jsmith | finance | 高使用量 |
步骤 6:狩猎持久化机制
此查询展示了 [DATE_TRUNC](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions/date_trunc "DATE_TRUNC") 如何支持对持久化机制进行时间类型分析,通过时间分桶和 [COUNT_DISTINCT](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/aggregation-functions/count_distinct "COUNT_DISTINCT") 识别快速连续创建任务或跨多个时间窗口建立持久化等可疑模式。
less
`
1. FROM process-logs
2. | WHERE process.name == "schtasks.exe" AND process.command_line:"/create" #1
3. | LOOKUP JOIN asset-inventory ON host.name
4. | LOOKUP JOIN user-context ON user.name
5. | EVAL time_bucket = DATE_TRUNC(1 hour, @timestamp) #2
6. | STATS task_creations = COUNT(*),
7. creation_hours = COUNT_DISTINCT(time_bucket) #3
8. BY user.name, host.name, asset.criticality
9. | WHERE task_creations > 0
10. | EVAL persistence_pattern = CASE(
11. creation_hours > 1, "Multiple Hours",
12. task_creations > 1, "Burst Creation",
13. "Single Task"
14. )
15. | SORT task_creations DESC
16. | LIMIT 1000
`Lobster AI
-
使用带有
:匹配运算符的[WHERE](https://www.elastic.co/docs/reference/query-languages/esql/commands/where "WHERE"),检测计划任务创建行为(这是一种常见的持久化机制)。 -
使用
[DATE_TRUNC](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/date-time-functions/date_trunc "DATE_TRUNC")将事件划分到按小时计算的时间桶中,以进行时间类型分析。 -
使用
[COUNT_DISTINCT](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/aggregation-functions/count_distinct "COUNT_DISTINCT")和time_bucket衡量任务创建速度。 -
使用
[CASE](https://www.elastic.co/docs/reference/query-languages/esql/functions-operators/conditional-functions-and-expressions/case "CASE")根据时间和频率对可疑模式进行分类。
响应
响应显示每个用户和主机的任务创建数量、创建时间以及持久化模式。
| task_creations | creation_hours | user.name | host.name | asset.criticality | persistence_pattern |
|---|---|---|---|---|---|
| 1 | 1 | jsmith | WS-001 | medium | 单个任务 |
| 1 | 1 | jsmith | SRV-001 | high | 单个任务 |
其他资源
-
在
elastic/detection-rulesGitHub 仓库中探索精选的威胁狩猎查询集合。- 对应的博客文章提供了有关如何在威胁狩猎工作流中使用这些查询的更多信息。
-
在以下博客文章中探索更多威胁狩猎示例:
提示
要了解可以在 Elastic Security 的哪些场景中使用 ES|QL,请参阅 ES|QL for security 概览。