4. Splunk搜索处理语言(SPL)基础
SPL(Search Processing Language)是 Splunk 中用于检索、转换、关联和呈现机器数据的核心语言。它的基本形态是一条以管道符 | 串联的命令链:最左侧通常是搜索命令,负责从索引中筛选原始事件;右侧的统计、字段提取、计算、排序等命令则对左侧结果逐级加工。理解 SPL 的关键,不是记住所有命令,而是理解“事件流如何被逐步收敛为可判断的安全结论”。
本节围绕安全事件调查中最常用的六类命令展开:search、stats、eval、rex、table、sort,并给出可直接套用的搜索模式。
一、search:先缩小范围,再谈分析
search 是隐式命令,通常写在管道最左侧。它的职责是从索引中拉取与条件匹配的事件。安全调查中,最忌讳一上来就 index=* 全量扫描,正确做法是用“索引 + 主机/用户/进程 + 时间窗 + 关键字段”四要素快速收敛。
index=win_security EventCode=4625
| search user!="ANONYMOUS LOGON"
| stats count by src_ip, user
| sort - count
这里 EventCode=4625 表示 Windows 登录失败,search user!="ANONYMOUS LOGON" 用于排除匿名登录噪声。注意:search 命令中的字段过滤发生在检索阶段,能显著减少后续命令处理的数据量,因此应尽量把过滤条件前置。
二、stats:把事件变成可判断的统计量
stats 是安全分析中使用频率最高的命令。它按指定字段分组,并计算 count、dc(去重计数)、sum、avg、values 等聚合值。安全场景中,dc 尤其重要,例如统计同一源 IP 尝试登录的不同账号数,可快速识别暴力破解或撞库行为。
index=win_security EventCode=4625
| stats count as fail_cnt, dc(user) as user_cnt,
values(user) as users by src_ip
| where fail_cnt > 20 AND user_cnt > 5
| sort - fail_cnt
该搜索输出每个源 IP 的失败次数、涉及账号数及账号列表,并用 where 过滤出“失败次数大于 20 且账号数大于 5”的可疑源。这是典型的“聚合 + 阈值判断”模式。
三、eval:生成新字段与判断逻辑
eval 用于创建或覆盖字段,支持算术、字符串、条件判断和时间函数。安全调查中常用它做风险打分、字段拼接和状态标记。
index=win_security EventCode=4625
| stats count as fail_cnt, dc(user) as user_cnt by src_ip
| eval risk = case(
fail_cnt > 100 AND user_cnt > 10, "high",
fail_cnt > 20 AND user_cnt > 5, "medium",
true(), "low")
| table src_ip, fail_cnt, user_cnt, risk
| sort - fail_cnt
case() 按顺序匹配条件,true() 作为兜底分支。这样就把原始失败事件转化为带风险等级的判断结果,便于后续告警或人工复核。
四、rex:从非结构化文本中提取字段
很多安全日志的关键信息藏在原始文本里,例如防火墙日志中的 URL、命令行参数、注册表路径。rex 通过正则表达式提取字段,语法为 rex field=源字段 "正则(?<新字段>...)"。
index=proxy
| rex field=_raw "Host:\s+(?<host>[^\s]+)"
| rex field=_raw "URI:\s+(?<uri>[^\s]+)"
| stats count by host, uri
| sort - count
提取后即可像普通字段一样参与 stats、where 和 table。需要注意:正则要尽量锚定上下文,避免误匹配;提取字段名不要与已有字段冲突。
五、table 与 sort:让结果可读、可排序
table 只保留指定字段并按列展示,适合生成调查视图;sort 按字段排序,- 表示降序。二者常配合使用,把统计结果整理成“一眼能看懂”的表格。
index=win_security EventCode=4625
| stats count as fail_cnt, dc(user) as user_cnt by src_ip
| eval risk = if(fail_cnt > 50, "high", "normal")
| table src_ip, fail_cnt, user_cnt, risk
| sort - fail_cnt
六、安全事件调查中的常用搜索模式
把上述命令组合起来,可形成几类高频调查模式:
- 暴力破解识别:
EventCode=4625 | stats count, dc(user) by src_ip | where count>20 - 账号异常登录:统计同一用户在不同
src_ip的登录次数,用dc(src_ip)判断是否异地。 - 进程链排查:对
EventCode=4688用rex提取命令行,再用table展示父进程与子进程。 - 横向移动线索:统计
EventCode=4624中Logon_Type=3的源 IP 与目标主机组合。
下面这张图概括了 SPL 从原始事件到安全结论的处理链,以及各命令在链中的位置与作用。
七、编写 SPL 时的实用建议
第一,过滤前置。把 index、sourcetype、EventCode 等条件写在最左侧,减少后续命令处理量。第二,先聚合再判断。用 stats 把海量事件压缩成少量统计行,再用 where 或 eval 做阈值判断,比逐条查看事件高效得多。第三,字段提取要克制。rex 正则应尽量精确,避免在大数据量上做复杂回溯。第四,结果要可读。table 控制列,sort 控制顺序,让调查结论一目了然。
stats 前后事件数量的变化,以及 eval 新增字段的效果。理解“事件流如何被收敛”,比记住命令语法更重要。