威胁狩猎实战:假设驱动查询与检测配置

威胁狩猎实战是安全运营从被动告警走向主动检测的关键能力。告警只能覆盖已知规则命中的场景,而攻击者使用系统自带工具、异常时间窗、低频凭据尝试时往往不触发任何规则。本文给出一套可落地的威胁狩猎流程:从数据源准备、假设设计、查询编写到用 Atomic Red Team 验证,并把有效假设固化为长期检测规则,附可直接执行的 auditd、ausearch、Sigma 与 Wazuh 配置。

适用场景

  • 已部署日志集中或 EDR,但每天只处理告警、缺少主动排查环节的安全团队。
  • 等保、关键信息基础设施保护要求提供”主动检测能力”证据的场景。
  • 出现业务系统异常但现有规则全部静默(无告警无日志异常)时,需要人工挖掘线索。
  • 重大漏洞预警发布后,需要在内部确认是否存在利用痕迹,而不是等 WAF 拦截记录。

需要区分三个概念:告警是规则命中后的被动通知,应急响应是已确认事件后的处置,威胁狩猎则是假设攻击者可能已经得手、主动去数据中寻找证据的过程。狩猎的产出不只是”有没有发现”,更重要的是把验证有效的假设固化成新的检测规则。

前置条件

  • 日志集中:Linux 主机已通过 rsyslog 或 journald 外发日志,关键主机部署 auditd;Windows 主机部署 Sysmon 并采集到集中平台。
  • 统一时间:所有主机启用 chrony 或 systemd-timesyncd,时钟偏差控制在 1 秒内,否则时间线无法拼接。
  • 资产清单:知道每台主机的角色、责任人、对外端口,否则无法判断行为是否异常。
  • 最小查询能力:不要求 SIEM,单机具备 ausearch、journalctl、grep 即可构成最小闭环。
  • 狩猎工具:建议安装 Atomic Red Team 或 atomic-operator 用于验证假设,atomic-operator 或 PowerShell 版 Invoke-AtomicTest 均可。

原理说明

威胁狩猎遵循一个闭环流程,通常称为狩猎循环:

  • 提出假设:基于攻击者战术(ATT&CK)推断”若攻击者用某种技术,会在数据里留下什么痕迹”。例如假设:攻击者用 curl 或 wget 从临时目录下载载荷。
  • 确定数据源:明确该假设需要哪类日志。进程执行看 execve 审计或 Sysmon Event ID 1,网络连接看 ss/netflow 或 Sysmon Event ID 3,凭据尝试看 sshd 日志。
  • 编写并执行查询:把假设翻译成可执行查询,先用宽条件捞全,再按父进程、路径、时间窗收窄。
  • 验证假设有效性:用 Atomic Red Team 在测试机复现该技术,确认查询确实能抓到;抓不到说明数据源或查询设计有问题。
  • 沉淀为检测规则:把有效查询写成 Sigma 规则、Wazuh 规则或 Suricata 规则,纳入常规告警,并做误报回归测试。

与应急响应最大的区别在于:狩猎的数据量通常是”安静的”,需要靠特征组合(父进程关系、路径、时间分布)而非单一黑名单触达结果。因此数据源的完整性和保留周期直接决定狩猎的上限。

操作步骤

步骤一:补齐高价值审计数据源

# /etc/audit/rules.d/hunt.rules
# 记录高危工具执行
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/curl  -k hunt_tool
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/wget  -k hunt_tool
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/nc    -k hunt_tool
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/socat -k hunt_tool

# 记录临时目录可执行行为
-a always,exit -F arch=b64 -S execve -F path=/tmp     -F perm=x -k hunt_tmp_exec
-a always,exit -F arch=b64 -S execve -F path=/var/tmp -F perm=x -k hunt_tmp_exec

# 记录权限提升相关行为
-a always,exit -F arch=b64 -S setuid -S setgid -k hunt_priv
-a always,exit -F arch=b64 -S init_module -S finit_module -k hunt_rootkit

# 记录敏感文件读取
-w /etc/shadow -p r -k hunt_cred
-w /root/.ssh/authorized_keys -p wa -k hunt_persist
# 加载并确认规则生效
augenrules --load
auditctl -l | grep -c hunt_

auditd 自身也应加固:日志外发到集中平台,本地开启防篡改,避免攻击者删除痕迹。同时确认日志保留满足狩猎需要,关键主机建议保留 90 天以上。

步骤二:设计狩猎假设

假设 对应 ATT&CK 数据源
攻击者用命令行工具下载载荷到临时目录 T1105 / T1059 execve 审计、Sysmon 1
Web 服务进程派生了 shell 或解释器 T1059 / T1505.003 进程父子关系
SSH 凭据尝试呈分布式低频特征 T1110 sshd 日志
计划任务被新增用于持久化 T1053.003 cron 文件审计、auditd
凭据文件被异常读取 T1003.008 文件访问审计

选择假设的原则是”高价值 + 可验证”。一次狩猎聚焦 3 到 5 条假设,5 天内不产生结论就应及时调整,不要在同一假设上无限投入。

步骤三:编写并执行查询

以第一条假设为例,先用 auditd 检索工具执行记录:

# 检索今天的工具执行,输出可读时间与命令行
ausearch -k hunt_tool -i --start today | aureport -f -i

# 聚合统计:哪个用户、哪个进程频繁调用这些工具
ausearch -k hunt_tool -i --start today \
  | grep -E '^type=EXECVE|^type=SYSCALL' \
  | awk '{print $0}' | sort | uniq -c | sort -rn | head -20

再用临时目录执行记录,重点找”Web 服务用户派生可执行文件”这类组合特征:

# 查出 /tmp 下被执行过的程序
ausearch -k hunt_tmp_exec -i --start today

# 结合 syslog 中的 nginx 用户行为
journalctl -u nginx --since "24 hours ago" | grep -iE "cannot execute|permission"

在集中日志平台上,用进程父子关系收窄误报:正常运维不会让 nginx 直接派生 shell。以 KQL 为例:

process.parent.name: ("nginx" or "php-fpm" or "apache2")
  and process.name: ("sh" or "bash" or "curl" or "wget" or "nc")

用 Sigma 形式表达同一检测逻辑,便于跨平台转换:

title: Web Server Spawning Download Utility
status: experimental
logsource:
  category: process_creation
  product: linux
detection:
  parent:
    ParentImage|endswith:
      - '/nginx'
      - '/php-fpm'
      - '/apache2'
  child:
    Image|endswith:
      - '/curl'
      - '/wget'
      - '/nc'
  condition: parent and child
level: high
tags:
  - attack.execution
  - attack.t1059

步骤四:用 Atomic Red Team 验证检测有效性

假设写完必须验证,否则无法区分”没有攻击”和”查询写错”。在测试机上执行对应原子测试:

# 查看某个技术的可用测试
atomic-operator run -t T1059.004 --show-details

# 执行单条测试并保留痕迹供检索
atomic-operator run -t T1059.004

# Windows 环境使用 PowerShell 版
# Invoke-AtomicTest T1105 -TestNumbers 1
# Invoke-AtomicTest T1053.003 -TestNumbers 2

执行后立即用步骤三的查询检索,确认能命中。若命中失败,依次检查:审计规则是否覆盖该路径、日志是否已外发、时间是否对齐、查询字段名是否与平台一致。

步骤五:固化为长期检测规则

假设验证有效后,应立即落成规则,避免下次再从零开始。以 Wazuh 规则为例:

<group name="threat_hunting,">
  <rule id="100210" level="10">
    <if_sid>80700</if_sid>
    <field name="audit.key">hunt_tmp_exec</field>
    <description>Temporary directory executable launched from \/tmp</description>
    <mitre>
      <id>T1059</id>
    </mitre>
  </rule>
</group>
# 校验规则语法(不同发行版路径略有差异)
/var/ossec/bin/wazuh-logtest
systemctl restart wazuh-manager

规则上线后要做误报回归:把业务系统正常行为(如监控脚本调用 curl、发布脚本调用 wget)加入白名单,白名单条目必须写明业务方与到期复核时间,避免长期累积成盲区。

配置验证

检查项 验证命令 期望结果
审计规则已加载 auditctl -l \| grep -c hunt_ 数量与配置一致,非 0
审计日志可检索 ausearch -k hunt_tool -i --start today 有结构化记录,字段完整
时间已对齐 chronyc tracking System time 偏差小于 0.1 秒
日志已外发 journalctl --since "10 min ago" \| grep -c audit 集中平台可看到同批记录
检测规则生效 Atomic 测试后重跑查询 查询命中且产生告警
规则语法正确 wazuh-logtest 无语法错误,能正确匹配

建议把”狩猎结论”写成固定模板存档:假设描述、查询语句、执行时间范围、数据源、命中数量、误报分析、是否固化为规则。这样下一次狩猎可以直接复用,也让检测能力可度量。

常见问题

FAQ 1:没有 SIEM 和 EDR,只有单机日志,能做威胁狩猎吗?

可以,最小闭环只需要 auditd 加 journalctl。落地建议:

# 单机最小狩猎组合
auditctl -l | grep hunt_                       # 确认数据源
ausearch -k hunt_tool -i --start today         # 进程执行
ausearch -k hunt_tmp_exec -i --start today     # 临时目录执行
journalctl _COMM=sshd --since "24 hours ago" \
  | grep -E "Accepted|Failed" | awk '{print $1,$2,$3,$11}' | sort | uniq -c

先只覆盖 3 到 5 条高价值假设,例如”Web 进程派生 shell””临时目录执行””SSH 凭据分布式尝试””authorized_keys 被写入””新增计划任务”。这些假设用单机日志就能验证,且命中后价值很高。等覆盖率稳定后再考虑上集中平台。

FAQ 2:狩猎结果误报太多,每天几百条,如何收敛?

误报高的根因通常是查询只用了单特征(只看命令名),没有用组合特征。收敛方法按优先级排列:

  • 加父进程约束:curl 被监控脚本调用是正常的,被 nginx 调用才是异常。父进程是性价比最高的收窄维度。
  • 加路径与用户约束:区分 /tmp 与业务发布目录,区分服务账户与运维账户。
  • 建立基线白名单:对确认安全的调用方登记白名单,白名单必须带责任人与复核时间。
  • 调整阈值与时间窗:低频分布式行为要靠单位时间内的尝试次数而非单条日志识别。

FAQ 3:日志要保留多久才够支撑狩猎?

保留周期取决于狩猎的起点时间。基准建议:

  • 关键主机与对外服务主机:90 至 180 天,至少覆盖一个季度。
  • 一般办公主机:30 至 90 天。
  • 网络设备与边界日志:不少于 90 天,便于回溯外联行为。

同时必须做两件事:本地日志外发到集中平台(单机日志易被攻击者清除),并与宿主机、容器、应用日志的时间线对齐。保留周期不足会让”攻击者三个月前留下的持久化”永远查不到。

总结

威胁狩猎实战的价值不在于某次是否抓到攻击者,而在于把安全运营从”等告警”变成”主动验证假设”。落地路径为:先用 auditd 与 Sysmon 补齐进程、凭据、持久化三类高价值数据源,再按 ATT&CK 设计 3 到 5 条可验证假设,用单特征捞全、用父进程与其他组合特征收窄,接着用 Atomic Red Team 复现验证查询有效性,最后把有效逻辑固化为 Sigma、Wazuh 或 Suricata 规则并做误报回归。把假设、查询、结论按模板存档,团队检测能力才会逐次累积,而不是每次重新摸索。