关于 detecting-ransomware-precursors-in-network
面向 SOC 和网络防御人员的安全技能,用于识别勒索软件加密前可能出现的网络活动。内容涵盖攻击链指标、检测规则、SIEM 关联、威胁情报和告警分级处置。
主要功能
- 01将网络信号映射到勒索软件攻击链
- 02部署 Suricata 和 Zeek 检测规则
- 03在 SIEM 中关联前兆事件
- 04接入勒索软件威胁情报源
- 05按置信度分级处置告警
适用场景
- 01检测 Cobalt Strike 回连和横向移动
- 02关联加密前的可疑事件
- 03调查可能存在的勒索软件立足点
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-ransomware-precursors-in-network安装后在 Claude Code 中输入/detecting-ransomware-precursors-in-network确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py详细介绍
检测网络流量中的勒索软件前兆
何时使用
- 为勒索软件攻击前的网络活动构建检测规则(从 Cobalt Strike 部署到加密的平均时间为 17 分钟)
- 监控勒索软件部署之前的初始访问代理(IAB)指标
- 创建 SIEM 关联规则,将多个前兆事件串联为高置信度告警
- 调整网络检测系统,以区分勒索软件准备活动与正常管理活动
- 调查可能表明勒索软件运营者已建立立足点的可疑网络模式
不要使用于加密后响应(参见 recovering-from-ransomware-attack)。本技能关注加密前的检测窗口,在此期间进行遏制可以防止数据丢失。
前提条件
- 在网络 TAP 或 SPAN 端口上部署网络检测平台(Zeek/Bro、Suricata 或 Arkime/Moloch)
- SIEM 平台(Splunk、Elastic Security、Microsoft Sentinel 或 QRadar)摄取网络日志
- 覆盖勒索软件 IOC 的威胁情报源(CISA、abuse.ch、OTX、MISP)
- 来自核心路由器和防火墙的网络流数据(NetFlow/IPFIX)
- 来自内部解析器的 DNS 查询日志
- 用于事件调查的完整数据包捕获能力
工作流
步骤 1:识别网络流量中的勒索软件杀伤链阶段
将网络可观测指标映射到每个加密前阶段:
| 杀伤链阶段 | 网络指标 | 检测来源 |
|---|---|---|
| 初始访问 | RDP 暴力破解、VPN 凭据填充、钓鱼回连 | 防火墙日志、IDS、代理日志 |
| C2 建立 | Cobalt Strike 信标(HTTPS/DNS)、Sliver/Brute Ratel 回连 | Zeek SSL/HTTP 日志、DNS 日志 |
| 凭据收集 | NTLM 中继、Kerberoasting、DCSync 流量 | Zeek Kerberos/NTLM 日志、DC 日志 |
| 侦察 | 内部端口扫描、AD 枚举(LDAP/SMB) | Zeek conn.log、流数据 |
| 横向移动 | PsExec/WMI/WinRM 流量、RDP 跳板、SMB 文件复制 | Zeek SMB/DCE-RPC 日志 |
| 准备 | 数据聚合、创建归档、云上传准备 | 代理日志、DNS 日志、DLP |
步骤 2:部署网络检测规则
针对常见勒索软件前兆的 Suricata 规则:
# Cobalt Strike default HTTPS beacon profile detection
alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"RANSOMWARE PRECURSOR - Cobalt Strike Default TLS Certificate"; tls.cert_subject; content:"Major Cobalt Strike"; sid:3000001; rev:1;)
# Cobalt Strike DNS beacon
alert dns $HOME_NET any -> any 53 (msg:"RANSOMWARE PRECURSOR - Cobalt Strike DNS Beacon Pattern"; dns.query; pcre:"/^[a-z0-9]{3}\.[a-z]{4,8}\./"; threshold:type both, track by_src, count 50, seconds 60; sid:3000002; rev:1;)
# Mimikatz network signature (DCSync - DRS GetNCChanges)
alert tcp $HOME_NET any -> $HOME_NET 135 (msg:"RANSOMWARE PRECURSOR - Possible DCSync/Mimikatz"; content:"|05 00 0b|"; offset:0; depth:3; content:"|e3 51 4d 2b 4b 47 15 d2|"; sid:3000003; rev:1;)
# Internal network scanning (many connections, few bytes)
alert tcp $HOME_NET any -> $HOME_NET any (msg:"RANSOMWARE PRECURSOR - Internal Port Scan"; flags:S; threshold:type both, track by_src, count 100, seconds 10; sid:3000004; rev:1;)
# PsExec service installation over SMB
alert tcp $HOME_NET any -> $HOME_NET 445 (msg:"RANSOMWARE PRECURSOR - PsExec Service Install"; content:"|ff|SMB"; content:"PSEXESVC"; nocase; sid:3000005; rev:1;)
# RDP brute force from internal host (lateral movement)
alert tcp $HOME_NET any -> $HOME_NET 3389 (msg:"RANSOMWARE PRECURSOR - Internal RDP Brute Force"; flow:to_server,established; threshold:type both, track by_src, count 20, seconds 60; sid:3000006; rev:1;)
# Large SMB file transfer (data staging)
alert tcp $HOME_NET any -> $HOME_NET 445 (msg:"RANSOMWARE PRECURSOR - Large SMB Transfer Possible Staging"; flow:to_server,established; dsize:>60000; threshold:type both, track by_src, count 100, seconds 300; sid:3000007; rev:1;)
用于行为检测的 Zeek 脚本:
# detect_ransomware_precursors.zeek
# Detect high volume of failed SMB connections (credential testing)
@load base/protocols/smb
module RansomwarePrecursor;
export {
redef enum Notice::Type += {
SMB_Brute_Force,
Suspicious_Internal_Scan,
Excessive_DNS_Queries,
SMB_Admin_Share_Access,
};
const smb_fail_threshold = 10 &redef;
const scan_threshold = 50 &redef;
const dns_query_threshold = 200 &redef;
}
global smb_fail_count: table[addr] of count &default=0 &create_expire=5min;
global conn_count: table[addr] of set[addr] &create_expire=1min;
event smb2_message(c: connection, hdr: SMB2::Header, is_orig: bool) {
if (hdr$status != 0) {
++smb_fail_count[c$id$orig_h];
if (smb_fail_count[c$id$orig_h] >= smb_fail_threshold) {
NOTICE([$note=SMB_Brute_Force,
$msg=fmt("Host %s has %d failed SMB attempts", c$id$orig_h, smb_fail_count[c$id$orig_h]),
$src=c$id$orig_h,
$identifier=cat(c$id$orig_h)]);
}
}
}
event new_connection(c: connection) {
if (c$id$orig_h in Site::local_nets && c$id$resp_h in Site::local_nets) {
if (c$id$orig_h !in conn_count)
conn_count[c$id$orig_h] = set();
add conn_count[c$id$orig_h][c$id$resp_h];
if (|conn_count[c$id$orig_h]| >= scan_threshold) {
NOTICE([$note=Suspicious_Internal_Scan,
$msg=fmt("Host %s connected to %d internal hosts in 1 min", c$id$orig_h, |conn_count[c$id$orig_h]|),
$src=c$id$orig_h,
$identifier=cat(c$id$orig_h)]);
}
}
}
步骤 3:创建 SIEM 关联规则
针对勒索软件前兆链的 Splunk 关联:
| tstats count FROM datamodel=Network_Traffic
WHERE earliest=-24h All_Traffic.dest_port IN (445, 135, 139, 3389, 5985, 5986)
AND All_Traffic.src_ip IN 10.0.0.0/8
AND All_Traffic.dest_ip IN 10.0.0.0/8
BY All_Traffic.src_ip, All_Traffic.dest_port, _time span=1h
| stats dc(All_Traffic.dest_port) as port_count,
values(All_Traffic.dest_port) as ports,
count as total_conns
BY All_Traffic.src_ip
| where port_count >= 3 AND total_conns > 50
| rename All_Traffic.src_ip as src_ip
| lookup threat_intel_ioc ip as src_ip OUTPUT threat_type
| eval risk_score = case(
port_count >= 5 AND total_conns > 200, "CRITICAL",
port_count >= 3 AND total_conns > 50, "HIGH",
1=1, "MEDIUM")
| table src_ip, ports, port_count, total_conns, risk_score, threat_type
Microsoft Sentinel KQL - 勒索软件前兆关联:
let timeframe = 24h;
let RDPBruteForce = SecurityEvent
| where TimeGenerated > ago(timeframe)
| where EventID == 4625
| where LogonType == 10
| summarize FailedRDP = count() by TargetAccount, IpAddress, bin(TimeGenerated, 1h)
| where FailedRDP > 10;
let SuspiciousSMB = SecurityEvent
| where TimeGenerated > ago(timeframe)
| where EventID == 5145
| where ShareName has "ADMIN$" or ShareName has "C$" or ShareName has "IPC$"
| summarize AdminShareAccess = count() by SubjectUserName, IpAddress, bin(TimeGenerated, 1h)
| where AdminShareAccess > 5;
let ServiceInstalls = SecurityEvent
| where TimeGenerated > ago(timeframe)
| where EventID == 7045
| where ServiceName has_any ("PSEXESVC", "meterpreter", "beacon");
RDPBruteForce
| join kind=inner SuspiciousSMB on IpAddress
| project TimeGenerated, IpAddress, TargetAccount, FailedRDP, SubjectUserName, AdminShareAccess
| extend AlertTitle = "Ransomware Precursor: RDP Brute Force + Admin Share Access"
步骤 4:集成威胁情报
为已知勒索软件基础设施配置自动化 IOC 源:
# Download and update ransomware C2 blocklists
# abuse.ch Feodo Tracker (Cobalt Strike, TrickBot, BazarLoader C2s)
curl -s https://feodotracker.abuse.ch/downloads/ipblocklist.csv | \
grep -v "^#" | cut -d, -f2 > /opt/threat-intel/feodo_ips.txt
# abuse.ch URLhaus (malware distribution URLs)
curl -s https://urlhaus.abuse.ch/downloads/csv_recent/ | \
grep -v "^#" | cut -d, -f3 > /opt/threat-intel/urlhaus_urls.txt
# abuse.ch ThreatFox (ransomware IOCs)
curl -s https://threatfox.abuse.ch/export/csv/recent/ | \
grep -i "ransomware" | cut -d, -f3 > /opt/threat-intel/ransomware_iocs.txt
# CISA Known Exploited Vulnerabilities (initial access vectors)
curl -s https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json | \
python3 -c "import json,sys; data=json.load(sys.stdin); [print(v['cveID'],v['vendorProject'],v['product']) for v in data['vulnerabilities'] if 'ransomware' in v.get('knownRansomwareCampaignUse','').lower()]"
步骤 5:建立告警分类与升级
根据前兆置信度定义分类程序:
| 告警类型 | 置信度 | 响应时间 | 操作 |
|---|---|---|---|
| 已确认的 Cobalt Strike 信标 | 高 | 15 分钟 | 立即隔离主机,触发 IR |
| 来自非 DC 的 DCSync/Kerberoasting | 高 | 15 分钟 | 禁用账户,隔离主机,触发 IR |
| 内部端口扫描 + 管理共享访问 | 中高 | 30 分钟 | 调查源主机,检查 EDR 遥测 |
| 来自内部主机的 RDP 暴力破解 | 中 | 1 小时 | 验证是否为合法管理活动,检查主机 |
| 异常 DNS 查询量 | 低中 | 4 小时 | 检查 DNS 隧道,与其他告警关联 |
核心概念
| 术语 | 定义 |
|---|---|
| 勒索软件前兆 | 先于勒索软件加密发生的网络活动,包括 C2 通信、横向移动和数据暂存 |
| 驻留时间 | 从初始入侵到勒索软件部署之间的时间,平均为 21 天,但有时短至 17 分钟 |
| 初始访问代理 (IAB) | 在暗网市场上将已入侵的网络访问权出售给勒索软件运营者的威胁行为者 |
| 信标行为 | 植入物(Cobalt Strike、Sliver)发出的周期性 C2 回调,可通过分析连接时序模式来检测 |
| Kerberoasting | 请求 Kerberos 服务票据以进行离线破解的凭据收集技术,可通过异常的 TGS-REQ 模式检测 |
| DCSync | 利用目录复制服务从域控制器提取密码哈希的技术,是关键的勒索软件前兆 |
工具与系统
- Zeek(原名 Bro):网络分析框架,为 SMB、Kerberos、DNS、HTTP 和 TLS 连接生成结构化日志
- Suricata:高性能 IDS/IPS,支持协议分析和多线程,用于勒索软件特征检测
- Arkime(原名 Moloch):全数据包捕获和搜索平台,用于对网络事件进行深度取证调查
- RITA (Real Intelligence Threat Analytics):开源工具,用于检测 Zeek 日志中的信标行为、DNS 隧道和长连接
- AC-Hunter:来自 Active Countermeasures 的网络威胁狩猎平台,用于信标检测和 C2 识别
常见场景
场景:在制造业网络中检测 LockBit 前兆
背景:一家制造企业的 SOC 收到告警,称工程部门的一台工作站 (10.1.5.42) 出现异常 SMB 流量。该工作站在凌晨 2:00 的 5 分钟内连接了 47 台内部主机的 445 端口。
方法:
- Zeek conn.log 分析显示,10.1.5.42 在 01:55-02:05 期间向 47 个唯一内部 IP 的 445、135 和 3389 端口发起了连接
- Zeek ssl.log 显示每 60 秒向 185.x.x.x 发起一次出站 HTTPS 连接,载荷一致为 48 字节(Cobalt Strike 信标模式)
- RITA 信标分析确认该外部 IP 的信标评分很高 (0.96),抖动为 60 秒
- Zeek kerberos.log 显示 10.1.5.42 对多个 SPN 账户发起 TGS-REQ(Kerberoasting)
- SMB tree_connect 事件显示对 12 台主机的 ADMIN$ 共享进行了访问(横向移动暂存)
- 遏制:隔离主机,重置工程用户的凭据,部署针对 C2 IP 的阻断规则
- 在勒索软件部署开始之前启动全面 IR
陷阱:
- 未核实来源是否为授权扫描器,就将内部端口扫描视为漏洞扫描器活动而不予理会
- 未将单个低危告警(DNS 异常 + SMB 访问 + 登录失败)关联为高危攻击链
- 为避免误报而将检测阈值设得过高,从而漏掉低速慢速侦察
- 忽视加密流量分析(JA3/JA4 指纹识别),而该分析即使在 TLS 隧道中也能识别 Cobalt Strike
输出格式
## Ransomware Precursor Detection Alert
**Alert ID**: [SIEM-generated ID]
**Detection Time**: [Timestamp]
**Source Host**: [IP / Hostname]
**Confidence**: [High / Medium / Low]
**Kill Chain Phase**: [Initial Access / C2 / Credential Harvest / Recon / Lateral Movement / Staging]
### Indicators Detected
| Indicator | Source | Detail | MITRE ATT&CK |
|-----------|--------|--------|--------------|
| [Type] | [Zeek/Suricata/SIEM] | [Description] | [T-ID] |
### Correlation Chain
1. [Timestamp] - [Event 1]
2. [Timestamp] - [Event 2]
3. [Timestamp] - [Event 3]
### Recommended Actions
- [ ] Isolate source host from network
- [ ] Check EDR telemetry for host-based indicators
- [ ] Reset credentials for affected user accounts
- [ ] Block identified C2 infrastructure
- [ ] Escalate to incident response team
评论
支持 Markdown