Splunk语句学习
基本概念
搜索管道:SPL是一个由
|管道符连接的命令序列。前一个命令的输出是最好一个命令的输入。像流水线一样,数据被一步步加工、过滤和统计。时间范围:时间敏感,要选择时间范围,或者在查询中使用earliest和latest。
字段:日志被解析后,会提取出关键字段。
关键命令
search-基础过滤
用途:过滤事件。它是隐式的,通常可以忽略
语法:关键词或字段名=值
示例
// 搜索包含 "Failed" 的事件
Failed
// 搜索来源IP是特定地址的事件
src_ip="192.168.1.10"
// 组合搜索:失败的登录,且来自该IP
Failed Passworrd src_ip="192.168.1.10"
// 使用通配符
user="admin*"
//如果创建了一个宏,其定义为user="admin*",并给这个宏取名为search_admin_users
`search_admin_users`//可以用反引号引用已经定义好的宏
|stats count by departmentwhere-条件过滤
用途:在已经搜索或统计出结果后,进行更精确的二次过滤。通常用在
stats、eval等命令之后。示例
// 只显示登录失败次数大于5的用户和IP组合
..|stats count by user,src_ip|where count > 5stats-统计聚合(超级重要)
用途:对数据进行统计计算,是分析的核心
常用函数:
count、sum()、avg()、dc()(去重函数)、values()(列出所有值)示例:
// 统计总事件数
..|stats count
// 按源IP统计事件数
..|stats count by src_ip
// 按用户统计,并计算平均登录时长(假设有duration字段)
..|stats count,avg(duration) by user
// 列出每个IP尝试登录过的所有用户
..|stats values(user) by src_ipeval-计算字段(超级重要)
用途:创建新的临时字段或现有字段进行统计
常用场景:数据格式化、条件判断、数学计算
示例
// 创建一个新字段,标识高风险IP(假设列表为10.0.0.0/8)
..|eval risk_ip=if(cidmatch("10.0.0.0/8",src_ip),"High","Normal")
// 计算两个时间戳的差值
..|eval response_time=end_time-start_time
// 使用case进行多条件判断
..|eval risk_level=case(
count >100,"Critical",
count >50,"High",
count >10,"Medium",
1==1,"Low"//1==1 表示默认情况
)if(condition,value_if_true,value_if_false):条件判断语句
cidmatch("CIDR_notation",ip_field):这是一个专门用于IP地址匹配的函数。"10.0.0.0/8"是一个用CIDR表示法定义 的IP地址段,10.0.0.0是网络地址,/8表示子网掩码为8位,这个网段包含了从10.0.0.0到10.10.255.255的所有IP地址,这是一个 私有地址空间。
table-制表
用途:将结果以清晰的表格形式展现,,只保留你关心的字段
示例
// 从复杂的结果中,提取出最关键的几列展示给领导或同事。
...|table _time,user,src_ip,actionrex-正则提取
用途:从非结构化的日志中提取结构化的字段
示例
...|rex field=_raw"user:(?<user>\w+)"
//字面匹配在非结构化的_raw中找到user,并将(一个或多个单词字符)匹配到的字段填入新字段user正则表达式核心知识点概览(针对日志分析)
1. 基本概念
在Splunk中的用途:从非结构化的日志(
_raw)中提取出结构化的字段
2. 核心语法元件
元件 | 描述 | Splunk日志分析示例 |
字面字符 | 匹配自身。 |
匹配字符串 "admin" |
元字符 | 具有特殊含义的字符。 |
|
字符集 | 匹配括号内的任意一个字符。 |
匹配任一元音字母。 匹配 "gray" 或 "grey"。 |
范围 | 在字符集内,表示一个字符范围。 |
匹配一个数字。 匹配一个字母。 |
取反 | 在字符集内,匹配不在括号内的任何字符。 |
匹配一个非数字字符。 |
3. 预定义字符类(常用快捷方式)
字符类 | 等价于 | 描述 |
|
| 数字。日志分析中最常用之一。 |
|
| 单词字符(字母、数字、下划线)。日志分析中最常用之一。 |
|
| 空白字符(空格、制表符、换行等)。 |
|
| 非数字。 |
|
| 非单词字符。 |
|
| 非空白字符。 |
4. 量词(控制匹配次数)
量词 | 描述 | 示例 |
| 0次或多次 |
匹配 "", "1", "123" |
| 1次或多次 |
匹配 "1", "123" (更常用,更精确) |
| 0次或1次 |
匹配 "http" 或 "https" |
| 恰好 n 次 |
匹配恰好4位数字(如年份)。 |
| n次或更多 次 |
匹配至少3个单词字符。 |
| n到m 次 |
匹配1到3位数字(如IP地址的一段)。 |
5. 分组与捕获()
分组
():将多个元素组合为一个整体,以便对其应用量词。捕获组
(?<field_name>...):这是Splunkrex命令的精髓
括号内匹配到的文本会被提取出来。
?<field_name>指定Splunk将匹配到的文本存入哪个新字段
示例剖析
...|rex field=_raw"user:(?<user>\w+)"
//找到字符串"user",将(一个或多个单词字符)捕获到的内容放入名为user的新字段中。6. 位置锚点
锚点 | 描述 | 示例 |
| 匹配字符串的开始。 |
匹配以 "Error" 开头的行。 |
| 匹配字符串的结束。 |
匹配以 "failed" 结尾的行。 |
7. 贪婪vs非贪婪匹配
贪婪
.*:匹配尽可能多的字符。(默认行为)非贪婪
.*?:匹配尽可能少的字符。示例
日志:data="important_info;more_data"
data="(.*)"→ 捕获到:important_info;more_data
data="(.*?)"→ 捕获到:important_info(在遇到第一个 " 时就停止)
transaction-事务分析
用途:将属于同一个会话或流程的多个事件关联在一起
常用场景:追踪一次完整的登录流程、一次Web会话等。
示例
// 将相同 "session_id" 的事件合并为一个事务,最大时间跨度5分钟
..|transaction session_id maxspan =5m
// 统计每个事务的持续时间、事件数量
...|transaction sesssion_id startwith="start" endwith="end"|table session_id,duration,eventcount join-关联查询
用途:将两个搜索结果通过一个共同字段进行关联
示例
// 先搜索防火墙日志,得到封锁的IP列表
search index=firewall action=block|stats count by src_ip|table src_ip
// 然后关联Web访问日志,查看这些IP在封锁前访问过哪些URL
|join type=inner src_ip[search index=web_access]//这里使用了内连接,只保留在两个数据集中都存在的键所对应的记录
实战场景
暴力破解攻击排查
index=auth action="failed"//首先搜索所有登录失败的事件
|stats count by src_ip,user//按源ip和用户名进行分组统计
|where count>10//过滤出失败次数大于10次的
|sort -count//按失败次数降序排序
|table user,src_ip,count//表格显示数据外泄嫌疑调查
// 目标:找出内部员工在短时间内向外网IP发起了大量连接(例如,通过SMB或FTP)的异常行为。
index=netconn dest_ip!=10.0.0.0/8 dest_ip!=172.16.0.0/12 dest_ip!=192.168.0.0./16//在出站连接日志中寻找非内部地址
|stats count,sum(bytes_sent) as total_bytes_sent by src_ip,dest_ip//按源ip和目的ip统计连接次数和连接量
|where total_bytes_sent>100000000//过滤发送数据量大于100MB的异常连接
|sort -total_bytes_sent //按数据量降序排序
|table src_ip,dest_ip,count,total_bytes_sent//制表Web应用攻击(SQL注入)检测
//目标:从web访问日志中检测潜在的SQL注入攻击
index=web_access
|where url LIKE "%union%select%" OR url LIKE "%1=1%" OR url LIKE "%sleep(%"
| rex field=url "(?i)(union\s+select|\'1\'=\'1\'|waitfor\s+delay)"//(?i)表示不区分大小写,这里的|表示或
| stats count values(url) as attacked_url by src_ip
|table src_ip,attacked_urls,count