Performs UEBA on SIEM logs with Splunk queries to detect anomalous user activities like impossible travel, abnormal login times, access patterns, and privilege abuse. For SOC teams identifying compromised accounts or insider threats.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
以下情况使用本技能:
Performs UEBA to detect anomalous user activities like impossible travel, unusual access patterns, privilege abuse, and insider threats using Splunk SIEM baselines and statistical analysis. For SOC teams spotting compromised accounts.
Detects anomalous user activities like impossible travel, unusual access, privilege abuse, and insider threats using Splunk UEBA baselines and stats. For SOC compromised account detection.
Detects anomalous authentication patterns using UEBA, statistical baselines, and ML models to identify impossible travel, brute force, credential stuffing, password spraying, and account takeovers from auth logs like Azure AD and Okta.
Share bugs, ideas, or general feedback.
以下情况使用本技能:
不适用于作为纪律处分的唯一依据 —— UEBA 发现是需要调查的指标,而非恶意意图的证明。
从历史数据创建行为基线:
index=auth sourcetype IN ("o365:management:activity", "vpn_logs", "WinEventLog:Security")
earliest=-30d latest=-1d
| stats dc(src_ip) AS unique_ips,
dc(src_country) AS unique_countries,
dc(app) AS unique_apps,
count AS total_logins,
earliest(_time) AS first_login,
latest(_time) AS last_login,
values(src_country) AS countries,
avg(eval(strftime(_time, "%H"))) AS avg_login_hour,
stdev(eval(strftime(_time, "%H"))) AS stdev_login_hour
by user
| eval avg_daily_logins = round(total_logins / 30, 1)
| eval login_hour_range = round(avg_login_hour, 0)." +/- ".round(stdev_login_hour, 1)." 小时"
| table user, unique_ips, unique_countries, unique_apps, avg_daily_logins,
login_hour_range, countries
识别在不可能的时间内从地理位置相距遥远的地点进行的登录:
index=auth sourcetype IN ("o365:management:activity", "vpn_logs")
action=success earliest=-24h
| iplocation src_ip
| sort user, _time
| streamstats current=f last(lat) AS prev_lat, last(lon) AS prev_lon,
last(_time) AS prev_time, last(City) AS prev_city,
last(Country) AS prev_country, last(src_ip) AS prev_ip
by user
| where isnotnull(prev_lat)
| eval distance_km = round(
6371 * acos(
cos(pi()/180 * lat) * cos(pi()/180 * prev_lat) *
cos(pi()/180 * (lon - prev_lon)) +
sin(pi()/180 * lat) * sin(pi()/180 * prev_lat)
), 0)
| eval time_diff_hours = round((_time - prev_time) / 3600, 2)
| eval speed_kmh = if(time_diff_hours > 0, round(distance_km / time_diff_hours, 0), 0)
| where speed_kmh > 900 AND distance_km > 500
| eval alert = "不可能旅行: ".prev_city.", ".prev_country." -> ".City.", ".Country
| table _time, user, prev_city, prev_country, City, Country, distance_km,
time_diff_hours, speed_kmh, alert
| sort - speed_kmh
识别用户正常工作时间之外的登录:
index=auth action=success earliest=-7d
| eval hour = strftime(_time, "%H")
| eval day_of_week = strftime(_time, "%A")
| eval is_weekend = if(day_of_week IN ("Saturday", "Sunday"), 1, 0)
| eval is_off_hours = if(hour < 6 OR hour > 22, 1, 0)
| join user type=left [
search index=auth action=success earliest=-60d latest=-7d
| eval hour = strftime(_time, "%H")
| stats avg(hour) AS baseline_avg_hour, stdev(hour) AS baseline_stdev_hour,
perc95(hour) AS baseline_latest_hour by user
]
| where (is_off_hours=1 OR is_weekend=1) AND
(hour > baseline_latest_hour + 2 OR hour < baseline_avg_hour - baseline_stdev_hour * 2)
| stats count, values(hour) AS login_hours, values(day_of_week) AS login_days,
values(src_ip) AS source_ips
by user, baseline_avg_hour, baseline_latest_hour
| where count > 0
| sort - count
监控异常文件或数据库访问量:
index=file_access OR index=sharepoint earliest=-24h
| stats sum(bytes) AS total_bytes, dc(file_path) AS unique_files,
count AS access_count by user
| join user type=left [
search index=file_access OR index=sharepoint earliest=-30d latest=-1d
| stats avg(eval(count)) AS baseline_avg_files,
stdev(eval(count)) AS baseline_stdev_files,
avg(eval(sum(bytes))) AS baseline_avg_bytes
by user
]
| eval bytes_gb = round(total_bytes / 1073741824, 2)
| eval z_score_files = round((unique_files - baseline_avg_files) / baseline_stdev_files, 2)
| where z_score_files > 3 OR bytes_gb > 5
| eval anomaly_level = case(
z_score_files > 5, "严重",
z_score_files > 3, "高",
bytes_gb > 10, "严重",
bytes_gb > 5, "高",
1=1, "中"
)
| sort - z_score_files
| table user, unique_files, bytes_gb, baseline_avg_files, z_score_files, anomaly_level
监控特权账户使用异常:
index=wineventlog sourcetype="WinEventLog:Security"
(EventCode=4672 OR EventCode=4624 OR EventCode=4648) earliest=-24h
| eval is_privileged = if(EventCode=4672, 1, 0)
| eval is_explicit_cred = if(EventCode=4648, 1, 0)
| stats sum(is_privileged) AS priv_events,
sum(is_explicit_cred) AS explicit_cred_events,
dc(ComputerName) AS unique_hosts,
values(ComputerName) AS hosts_accessed
by TargetUserName, src_ip
| join TargetUserName type=left [
search index=wineventlog EventCode IN (4672, 4624, 4648) earliest=-30d latest=-1d
| stats dc(ComputerName) AS baseline_hosts,
avg(eval(count)) AS baseline_daily_events by TargetUserName
]
| where unique_hosts > baseline_hosts * 2 OR priv_events > baseline_daily_events * 3
| eval risk_score = (unique_hosts / baseline_hosts * 30) + (priv_events / baseline_daily_events * 20)
| sort - risk_score
| table TargetUserName, src_ip, unique_hosts, baseline_hosts, priv_events,
baseline_daily_events, risk_score, hosts_accessed
将所有 UEBA 信号聚合为综合风险评分:
| inputlookup ueba_impossible_travel.csv
| append [| inputlookup ueba_off_hours_access.csv]
| append [| inputlookup ueba_data_access_anomaly.csv]
| append [| inputlookup ueba_privilege_abuse.csv]
| stats sum(risk_points) AS total_risk,
values(anomaly_type) AS anomaly_types,
dc(anomaly_type) AS anomaly_count
by user
| lookup identity_lookup_expanded identity AS user
OUTPUT department, managedBy, priority AS user_priority
| eval final_risk = total_risk * case(
user_priority="critical", 2.0,
user_priority="high", 1.5,
user_priority="medium", 1.0,
1=1, 0.8
)
| sort - final_risk
| head 20
| table user, department, managedBy, anomaly_types, anomaly_count, total_risk, final_risk
| 术语 | 定义 |
|---|---|
| UEBA | 用户和实体行为分析(User and Entity Behavior Analytics)——针对既定基线检测异常的行为分析 |
| 不可能旅行 | 在使物理旅行不可能的时间框架内,从地理位置相距遥远的地点进行的登录事件 |
| 行为基线 | 从 30-90 天历史数据建立的用户正常活动模式的统计画像 |
| Z 分数 | 统计量,衡量观测值偏离均值的标准差数量——值 > 3 表示异常 |
| 风险评分 | 聚合多种行为异常并按资产重要性加权的综合数值评分 |
| 同伴组分析 | 将用户行为与同部门/角色的其他人进行比较以识别离群值 |
UEBA 异常报告 — 每周汇总
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
时间段: 2024-03-11 至 2024-03-17
基线用户数: 2,847
检测异常数: 23
高风险用户排名:
# 用户 部门 风险 异常
1. jsmith 财务 94.5 不可能旅行(纽约->莫斯科,2小时)、非工作时间访问、下载 15GB
2. admin_svc01 IT 运维 82.0 从 12 个新 IP 登录,访问 47 台主机(基线:8)
3. mwilson 人力资源 67.3 非工作时间文件访问(凌晨 2 点),下载量是正常的 3 倍
调查状态:
jsmith: 已上报 Tier 2 — 可能账户被攻陷(IR-2024-0445)
admin_svc01:审查中 — 可能是新的自动化部署(与 IT 运维确认中)
mwilson: 等待人力资源背景信息 — 员工在通知期内,已加强监控