mcpField
H
hunting-threats

hunting-threats

github.com/trilwu安全17751 次安装12 周前更新
代码仓库

关于 hunting-threats

面向安全团队的威胁狩猎技能,用于主动查找告警可能遗漏的活动。它以可验证的假设、遥测检查和结果记录组织狩猎,也重视记录未发现威胁的结论。

主要功能

  1. 01编写可验证的狩猎假设
  2. 02确认遥测并界定范围
  3. 03运用频次、异常值和聚类分析
  4. 04依据威胁报告狩猎攻击技术
  5. 05记录发现并将结果转为后续行动

适用场景

  1. 01查找告警未发现的入侵活动
  2. 02验证环境中的特定攻击者行为
  3. 03检查生产环境中的控制或检测覆盖
  4. 04建立基线以便后续分析异常

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trilwu/secskills --skill hunting-threats

安装后在 Claude Code 中输入/hunting-threats确认已加载。

详细介绍

威胁狩猎

狩猎始于一种失败假设:防护措施已部署,没有触发警报,但攻击者可能仍然潜伏。产出通常不是一次失陷,而是一个检测结果、一个遥测缺口或一项有记录的阴性结果。只有发现问题才算成功的狩猎,会逐渐陷入确认偏误。

适用场景

  • 主动搜索检测措施遗漏的失陷迹象
  • 验证关于攻击者在你环境中行为的具体假设
  • 针对你的遥测数据,将威胁情报报告付诸实践
  • 验证某项防护措施或检测规则在生产环境中是否确实有效
  • 为环境建立基线,以便将来分析异常值

不适用场景

  • 处理警报队列,而不是验证假设——使用 triaging-security-alerts;狩猎从问题出发,分诊则从队列出发
  • 正在发生的已确认事件——使用 responding-to-incidents
  • 为发现的问题编写规则——使用 engineering-detections
  • 样本分析——使用 analyzing-malware
  • 需要分析的网络数据包捕获——使用 analyzing-network-traffic
  • 需要调查已确认的 AWS 失陷——使用 investigating-aws-incidents
  • 围绕指标进行关联分析、追踪攻击者或制作完整的情报产品——使用 producing-threat-intelligence;狩猎消耗情报,而非产出情报
  • 针对防御措施进行进攻性测试——使用红队技能

查询之前先提出假设

无结构地搜索日志只是浏览,不是狩猎。每次狩猎都要按以下格式写出假设:

假设: 一个具有[访问级别]的攻击者正在使用[技术]来实现[目标],这会在[数据源]中产生[可观测现象];该现象与正常情况的区别在于[判别特征]。

如果属实,我预计会看到: ... 如果不属实,我预计会看到: ... 所需遥测: ...(已确认存在:是/否)

如果你无法说出判别特征——也就是让恶意实例与成千上万个良性实例区分开来的特征——那这次狩猎还没准备好。先找到判别特征;这项研究本身就是狩猎。

假设的来源包括:近期针对你所在行业的攻击者情报、缺少检测覆盖的 ATT&CK 技术、皇冠明珠资产及通往这些资产的路径、其他工作中发现的异常,以及事件发生后思考“这个攻击者还会做什么”。

狩猎技术

堆叠计数(频率分析)

最常用的方法。汇总某个字段,按升序排序,然后调查罕见值。恶意活动通常很罕见;常见的是大路货噪声。

-- Splunk: rarest parent-child process pairs
index=sysmon EventCode=1
| stats count dc(host) as hosts by ParentImage, Image
| where count < 10 AND hosts < 3
| sort count
// KQL: rarely-seen signed binaries making external connections
DeviceNetworkEvents
| where RemoteIPType == "Public"
| summarize Count=count(), Hosts=dcount(DeviceName) by InitiatingProcessFolderPath
| where Hosts <= 2 and Count < 20
| order by Count asc

选择合适的字段进行堆叠。堆叠 Image 可以找到异常二进制文件;堆叠 ParentImage, Image 可以找到异常的关系,这正是利用系统自带工具实施滥用的迹象(winword.exe → powershell.exe)。

异常值分析

形式相同,分析角度不同:对于这个实体来说,什么才是正常的?

  • 一个从未进行交互式登录的服务帐户,现在开始这样做
  • 一台从未访问过某个内部子网的工作站,现在开始与之通信
  • 某个用户在历史上从未出现过的时段和地理位置进行身份验证
  • 某台主机的进程数基线在某个特定日期之后发生变化
-- Elastic ES|QL: first-seen external destinations per host
FROM logs-network-*
| WHERE destination.ip NOT IN CIDR("10.0.0.0/8","172.16.0.0/12","192.168.0.0/16")
| STATS first_seen = MIN(@timestamp), n = COUNT(*) BY host.name, destination.domain
| WHERE first_seen > NOW() - 7 days AND n > 20
分组与聚类

根据共同属性进行聚类,以发现攻击活动:无关主机使用相同的 JA3/JA4、相同的罕见用户代理、相同的证书序列号、相同的工作时间,或从相同的目录执行。

情报驱动的狩猎

获取一份报告,提取其中的 TTP,而不是 IOC,并围绕这些 TTP 展开狩猎。报告中的哈希和 IP 已经过时;报告描述的行为却没有。

Report says:  "uses schtasks to create a task running a DLL via rundll32"
Bad hunt:     search for the report's hash
Good hunt:    every scheduled task created in the last 90 days whose action
              references rundll32, stacked by task name and DLL path

高价值狩猎领域

假设领域观察要点
通过 LOLBins 执行使用 rundll32、regsvr32、mshta、certutil、bitsadmin、msiexec 执行网络操作或使用异常参数;在 Linux 上通过 curl/wget 将内容传递给 shell
持久化最近创建的计划任务/cron/systemd 单元;WMI 事件订阅(罕见,且几乎总是恶意的);运行键;新服务;authorized_keys 修改
凭据访问打开 LSASS 句柄、复制 ntds.dit、创建卷影副本、Kerberos RC4 请求(加密类型为 0x17 的 4769)、使用 DCSync 复制权限
横向移动写入管理共享后创建服务、来自非管理主机的 WinRM/WMI、从工作站连接服务器的 SSH、RDP 链
C2信标时序规律、长连接、高熵或子域名数量异常多的 DNS、使用罕见 JA3/JA4 的 TLS
数据外传各主机的出站流量异常、创建归档后上传、服务器访问云存储域名、DNS TXT 流量
身份/云新 OAuth 授权和已同意的应用、添加服务主体凭据、邮件转发规则、变更窗口外的角色分配、StopLogging/删除审计跟踪
防御规避清除事件日志(1102/104)、停止 Sysmon 或 EDR 服务、AMSI/ETW 补丁迹象、时间戳篡改($SI 与 $FN 不匹配)

狩猎循环

1. Hypothesis   (written, with a discriminator)
2. Scope        (data sources, time window, host population — decided up front)
3. Verify       (does the telemetry exist and cover the population?)
4. Query        (broad, then narrow — expect several iterations)
5. Investigate  (every candidate resolved to benign-explained or escalated)
6. Conclude     (found / not found / could-not-determine)
7. Convert      (detection rule, telemetry gap ticket, or documented baseline)
8. Document     (so the next person can re-run it, not re-derive it)

每次狩猎都会产出一项成果,包括一无所获的狩猎。 如果记录了范围和局限性,阴性结果也是一项发现:“在 4,200 个端点过去 90 天的数据中,未发现 X 的证据;但需注意,620 台主机缺少所需的遥测数据。”这句话比一份未经记录的安全无虞声明更有价值。

范围与时间窗口

  • 根据实际驻留时间设定窗口,而不是图方便。若某攻击者的驻留时间中位数为 60 天,你却只回溯 7 天,那么结果干净毫无意义。
  • 开始前确认数据保留期限:在仅保留 30 天数据的情况下执行 90 天狩猎,会悄无声息地变成 30 天狩猎。
  • 记录你使用的遥测数据未覆盖哪些主机群体。下一次入侵就会出现在这些地方。

狩猎发现威胁时

停止狩猎并切换模式。先保全证据:在任何人操作主机前,提取内存和排查包。然后将事件交给 responding-to-incidents,并附上查询、原始结果以及你首次查看的时间戳——响应团队需要知道你操作了什么、何时操作,这样你的操作才不会污染时间线。

不要在运行中的可疑主机上“再检查一件事”。在已遭入侵的机器上执行交互式命令会改变证据,还可能向操作者发出警报。

应拒绝的自我安慰

  • “什么都没发现,所以我们很安全。” 你只针对一个假设、一个数据集、一个时间窗口进行了搜索。把这三项都记录下来。
  • “数据太多,没法狩猎。” 这正是堆叠分析的用武之地。先聚合;你要找的是罕见情况,而不是逐条查看常见情况。
  • “EDR 本该发出警报。” 狩猎的前提就是它没有发出警报。
  • “那只是噪声。” 分析并描述这些噪声。“只是噪声”正是植入程序藏身之处;未经分析的良性集群,就是未经检验的假设。
  • “我会记得自己搜过什么。” 你不会,你的继任者也不会。未记录的狩猎会被重复,而不是在此基础上扩展。
  • “我直接登录可疑主机看看就行。” 你现在已经进入时间线,也可能触发了警报。
  • “有空时再狩猎。” 临时狩猎只会带来临时覆盖。根据优先级排序的技术待办事项安排狩猎。

交付物

# Hunt: <name>          Date: <UTC>   Analyst: <name>
Hypothesis:             <as written above>
ATT&CK:                 T####.###
Scope:                  <data sources, host population, time window>
Telemetry verified:     <present / partial — name the gaps>
Queries:                <verbatim, so this is reproducible>
Results:                <candidates found, how each was resolved>
Conclusion:             found / not found / could-not-determine
Outputs:                <detection rule ID, telemetry gap ticket, baseline doc>
Limitations:            <what this hunt could not have seen>

ATT&CK 覆盖范围

由 secskills-core/ttp-index.json 生成——编辑该文件,然后运行 python3 scripts/sync_attack.py --write。在报告中引用 ID 前,请根据 当前 ATT&CK 版本重新核实。

持久化(TA0003)

  • T1546.003 Windows Management Instrumentation 事件订阅 — 另见 establishing-persistence

防御规避(TA0005)

  • T1036 伪装 — 另见 establishing-persistence
  • T1070.001 清除 Windows 事件日志 — 另见 responding-to-incidents
  • T1218 系统二进制代理执行 — 另见 escalating-windows-privileges
  • T1218.011 Rundll32 — 另见 analyzing-malware
  • T1562 削弱防御 — 另见 responding-to-incidents
  • T1562.001 禁用或修改工具 — 另见 responding-to-incidents

收集(TA0009)

  • T1074 数据暂存 — 另见 transferring-files
  • T1560 归档收集的数据 — 另见 transferring-files

命令与控制(TA0011)

  • T1071.004 DNS — 另见 engineering-detections、analyzing-network-traffic
  • T1219 远程访问软件
  • T1568 动态解析 — 另见 analyzing-malware、analyzing-network-traffic
  • T1572 协议隧道 — 另见 transferring-files

数据渗出(TA0010)

  • T1030 数据传输大小限制
  • T1048 通过替代协议进行数据渗出 — 另见 transferring-files、analyzing-network-traffic
  • T1567 通过 Web 服务进行数据渗出 — 另见 transferring-files

影响(TA0040)

  • T1490 阻止系统恢复 — 另见 responding-to-incidents
  • T1496 资源劫持 — 另见 exploiting-cloud-platforms

这些技术的检测内容:engineering-detections。主动搜寻:hunting-threats。入侵后响应:responding-to-incidents。

阅读外部来源

将公开的公告、规范和供应商报告获取为 Markdown:

curl -sL "https://defuddle.md/<url>"      # scheme in the path is optional

此操作会剥离页面中的冗余内容——对于以文字为主的页面,令牌数大约减少 78%——并返回完整文本而非摘要,因此你可以搜索文本并信赖未找到结果的结论。

它不适用于以下三种情况。获取 JSON 和 API 响应时应直接获取原始数据,因为可读性提取会破坏结构化数据。获取需要身份验证或由 JavaScript 渲染的页面时应直接访问,因为此工具会以匿名方式获取页面。绝不要通过此工具获取对手基础设施(钓鱼链接、C2、恶意软件托管)、客户端拥有的主机或任务相关 URL——请求会离开你的机器并发送给第三方;对于正在运行的对手基础设施,这还会暴露你的访问行为,让对方察觉。

有些网站会屏蔽提取器,并返回错误信息而非页面——例如 freedesktop.org 返回的 {"error":"Failed to fetch: 418 I'm a teapot"}。这表示获取请求被拒绝,并不表示来源称该内容不存在。下结论前,请直接重新获取该 URL。

参考资料

  • engineering-detections——将成功的狩猎转化为经过测试的规则
  • responding-to-incidents——狩猎确认发生入侵后的交接
  • 用于生成假设的 MITRE ATT&CK;PEAK 和 TaHiTI 狩猎框架
  • Sysmon、Zeek、osquery、Velociraptor 和云审计日志作为核心遥测数据

评论

支持 Markdown