The interface is localized. Skill descriptions and documents are machine-translated by AI into your language; code, commands, paths and technical terms stay in the original, and the author's document governs.
Explore skills
Productivity · SKILL.md

performing-user-behavior-analytics

performing-user-behavior-analytics

执行用户和实体行为分析(UEBA),通过基于 SIEM 的行为基线和统计分析, 检测异常用户活动,包括不可能旅行、异常访问模式、权限滥用和内部威胁。 适用于 SOC 团队通过偏离既定行为规范来识别被攻陷账户或内部威胁。

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill documentation

GitHub

name: performing-user-behavior-analytics description: > 执行用户和实体行为分析(UEBA),通过基于 SIEM 的行为基线和统计分析, 检测异常用户活动,包括不可能旅行、异常访问模式、权限滥用和内部威胁。 适用于 SOC 团队通过偏离既定行为规范来识别被攻陷账户或内部威胁。 domain: cybersecurity subdomain: soc-operations tags: [soc, ueba, user-behavior, insider-threat, anomaly-detection, splunk, baseline] version: "1.0" author: mahipal license: Apache-2.0

执行用户行为分析

适用场景

以下情况使用本技能:

  • SOC 团队需要通过异常认证模式检测被攻陷账户
  • 内部威胁项目需要超出基于规则检测的行为监控
  • 不可能旅行或地理异常表明凭据已被入侵
  • 特权账户监控需要基线偏差检测

不适用于作为纪律处分的唯一依据 —— UEBA 发现是需要调查的指标,而非恶意意图的证明。

前置条件

  • 具有 30 天以上认证和访问日志历史的 SIEM,用于基线创建
  • VPN、O365 和 Active Directory 认证日志规范化为 CIM
  • 用于基于位置的异常检测的 GeoIP 数据库(MaxMind GeoLite2)
  • 身份丰富数据(部门、角色、上级、典型工作时间)
  • 具有 UBA 模块的 Splunk Enterprise Security 或等效的 UEBA 能力

工作流程

步骤 1:建立用户认证基线

从历史数据创建行为基线:

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

步骤 2:检测不可能旅行

识别在不可能的时间内从地理位置相距遥远的地点进行的登录:

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

步骤 3:检测异常登录时间

识别用户正常工作时间之外的登录:

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

步骤 4:检测异常数据访问模式

监控异常文件或数据库访问量:

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

步骤 5:检测权限滥用模式

监控特权账户使用异常:

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

步骤 6:生成风险评分并优先排序调查

将所有 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 表示异常
风险评分聚合多种行为异常并按资产重要性加权的综合数值评分
同伴组分析将用户行为与同部门/角色的其他人进行比较以识别离群值

工具与系统

  • Splunk UBA:与 Splunk ES 集成的专用用户行为分析模块,提供 ML 驱动的异常检测
  • Microsoft Sentinel UEBA:Azure Sentinel 中的内置 UEBA 功能,具有实体页面和调查图
  • Exabeam Advanced Analytics:独立 UEBA 平台,具有会话拼接和自动时间线创建
  • Securonix:云原生 SIEM/UEBA,具有针对内部威胁检测的预建行为模型

常见场景

  • 账户被攻陷:不可能旅行 + 非工作时间登录 + 异常应用访问 = 可能的凭据被攻陷
  • 内部数据窃取:员工在离职前通知期内访问正常文件量的 10 倍
  • 权限提升滥用:管理员账户从异常位置访问正常范围之外的系统
  • 共享账户检测:服务账户同时从多个地理位置登录
  • 休眠账户重新激活:90 天以上无活动的账户突然执行特权操作

输出格式

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:    等待人力资源背景信息 — 员工在通知期内,已加强监控
Saved skills