Detects network reconnaissance and port scanning using Suricata and Snort IDS signatures, threshold rules, and traffic anomaly analysis. Identifies Nmap, Masscan, and custom scans.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cybersecurity-skills-zh:detecting-network-scanning-with-ids-signaturesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
网络扫描(network scanning)通常是攻击的第一阶段,攻击者使用 Nmap、Masscan、ZMap 和自定义扫描工具枚举活跃主机、开放端口、运行中的服务和操作系统版本。检测这种侦察活动可以为潜在攻击提供早期预警。Suricata 和 Snort 等 IDS/IPS 系统可通过三种方式识别扫描:基于签名的检测(匹配已知扫描工具的数据包模式)、基于阈值的检测(统计一段时间内的连接尝试次数)和异常检测(识别异常流量模式)。本技能涵盖编写和部署用于扫描检测的 IDS 签名、配置基于阈值的告警,以及将扫描活动与下游攻击指标进行关联。
网络扫描(network scanning)通常是攻击的第一阶段,攻击者使用 Nmap、Masscan、ZMap 和自定义扫描工具枚举活跃主机、开放端口、运行中的服务和操作系统版本。检测这种侦察活动可以为潜在攻击提供早期预警。Suricata 和 Snort 等 IDS/IPS 系统可通过三种方式识别扫描:基于签名的检测(匹配已知扫描工具的数据包模式)、基于阈值的检测(统计一段时间内的连接尝试次数)和异常检测(识别异常流量模式)。本技能涵盖编写和部署用于扫描检测的 IDS 签名、配置基于阈值的告警,以及将扫描活动与下游攻击指标进行关联。
| 扫描类型 | Nmap 参数 | 数据包特征 | 检测方法 |
|---|---|---|---|
| TCP SYN | -sS | 仅 SYN 标志,不完成握手 | 无 SYN/ACK 响应的 SYN 模式 |
| TCP Connect | -sT | 完整三次握手 | 来自单一来源的多个连接 |
| TCP FIN | -sF | 仅 FIN 标志 | FIN 发到关闭端口(RST 响应) |
| TCP Xmas | -sX | FIN+PSH+URG 标志 | 异常标志组合 |
| TCP NULL | -sN | 无标志位 | 零标志 TCP 数据包 |
| UDP Scan | -sU | UDP 发到多个端口 | ICMP 端口不可达响应 |
| ACK Scan | -sA | 仅 ACK 标志(探测防火墙) | 未经请求的 ACK 数据包 |
| SYN/ACK Scan | 自定义 | 没有先前 SYN 的 SYN+ACK | 状态违规 |
| OS 指纹识别 | -O | 异常 TCP 选项/窗口大小 | 特定选项组合 |
| 版本检测 | -sV | 服务探测字符串 | 已知探测载荷 |
| 模板 | Nmap 参数 | 速度 | 检测难度 |
|---|---|---|---|
| Paranoid | -T0 | 每 5 分钟 1 个探测 | 极难 |
| Sneaky | -T1 | 每 15 秒 1 个探测 | 困难 |
| Polite | -T2 | 每 0.4 秒 1 个探测 | 中等 |
| Normal | -T3 | 默认并行度 | 容易 |
| Aggressive | -T4 | 并行,1.25 秒超时 | 很容易 |
| Insane | -T5 | 最大并行度 | 极易 |
创建 /var/lib/suricata/rules/scan-detection.rules:
# === TCP 扫描检测 ===
# 检测 TCP SYN 扫描(大量 SYN 但未完成)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN TCP SYN Scan Detected"; flags:S,12; threshold:type both,track by_src,count 30,seconds 10; classtype:attempted-recon; sid:5000001; rev:2;)
# 检测 TCP FIN 扫描
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN TCP FIN Scan"; flags:F,12; threshold:type both,track by_src,count 20,seconds 60; classtype:attempted-recon; sid:5000002; rev:1;)
# 检测 TCP Xmas 扫描(FIN+PSH+URG)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN TCP Xmas Tree Scan"; flags:FPU,12; classtype:attempted-recon; sid:5000003; rev:1;)
# 检测 TCP NULL 扫描(无标志)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN TCP NULL Scan"; flags:0,12; classtype:attempted-recon; sid:5000004; rev:1;)
# 检测 ACK 扫描(探测防火墙)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN TCP ACK Scan"; flags:A,12; flow:stateless; threshold:type both,track by_src,count 50,seconds 30; classtype:attempted-recon; sid:5000005; rev:1;)
# 检测 SYN+ACK 扫描(异常无状态探测)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN TCP SYN-ACK Scan"; flags:SA,12; flow:stateless; threshold:type both,track by_src,count 30,seconds 30; classtype:attempted-recon; sid:5000006; rev:1;)
# === UDP 扫描检测 ===
# 检测 UDP 端口扫描
alert udp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN UDP Port Scan"; threshold:type both,track by_src,count 30,seconds 10; classtype:attempted-recon; sid:5000010; rev:1;)
# === Nmap 专项检测 ===
# 检测 Nmap 操作系统指纹识别(T1 探测——ECN SYN)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN Nmap OS Fingerprint Probe"; flags:SEC,12; window:1; classtype:attempted-recon; sid:5000020; rev:1;)
# 检测 Nmap 窗口扫描(特定窗口大小模式)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN Nmap Window Size Probe"; flags:A,12; flow:stateless; window:1024; threshold:type both,track by_src,count 10,seconds 30; classtype:attempted-recon; sid:5000021; rev:1;)
# 检测 Nmap 版本检测探测
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN Nmap Service Version Probe"; flow:established; content:"HELP"; depth:4; threshold:type both,track by_src,count 5,seconds 60; classtype:attempted-recon; sid:5000022; rev:1;)
# 检测 Nmap 脚本引擎(NSE)
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN Nmap NSE HTTP Script"; http.user_agent; content:"Nmap Scripting Engine"; classtype:attempted-recon; sid:5000023; rev:1;)
# === Masscan 检测 ===
# 检测 Masscan SYN 扫描(特定窗口大小)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"SCAN Masscan SYN Scan Detected"; flags:S,12; window:1024; threshold:type both,track by_src,count 100,seconds 10; classtype:attempted-recon; sid:5000030; rev:1;)
# === 内部扫描检测 ===
# 检测内部主机扫描(横向移动侦察)
alert tcp $HOME_NET any -> $HOME_NET any (msg:"SCAN Internal Network Scan Detected"; flags:S,12; threshold:type both,track by_src,count 50,seconds 30; classtype:attempted-recon; sid:5000040; rev:1;)
# 检测内部 ICMP 扫描
alert icmp $HOME_NET any -> $HOME_NET any (msg:"SCAN Internal ICMP Sweep"; itype:8; threshold:type both,track by_src,count 30,seconds 10; classtype:attempted-recon; sid:5000041; rev:1;)
编辑 /etc/suricata/threshold.config:
# 对已授权的漏洞扫描器抑制扫描告警
suppress gen_id 1, sig_id 5000001, track by_src, ip 10.0.5.100
suppress gen_id 1, sig_id 5000001, track by_src, ip 10.0.5.101
# 限制扫描告警速率,防止日志洪泛
rate_filter gen_id 1, sig_id 5000001, track by_src, count 5, seconds 300, new_action alert, timeout 600
rate_filter gen_id 1, sig_id 5000040, track by_src, count 3, seconds 300, new_action alert, timeout 600
# 关键内部扫描的事件过滤
event_filter gen_id 1, sig_id 5000040, type both, track by_src, count 1, seconds 60
#!/usr/bin/env python3
"""分析 IDS 告警中的网络扫描活动并生成报告。"""
import json
import sys
from collections import defaultdict
from datetime import datetime
class ScanDetector:
"""关联 IDS 告警以识别扫描活动。"""
def __init__(self):
self.scan_events = defaultdict(lambda: {
'source_ip': '',
'target_ips': set(),
'target_ports': set(),
'scan_types': set(),
'alert_count': 0,
'first_seen': None,
'last_seen': None,
'signatures': defaultdict(int),
})
def process_eve_json(self, filepath: str):
"""处理 Suricata EVE JSON 告警日志。"""
with open(filepath, 'r') as f:
for line in f:
try:
event = json.loads(line)
if event.get('event_type') != 'alert':
continue
alert = event.get('alert', {})
sig = alert.get('signature', '')
if 'SCAN' not in sig:
continue
src_ip = event.get('src_ip', '')
dst_ip = event.get('dest_ip', '')
dst_port = event.get('dest_port', 0)
ts = datetime.fromisoformat(
event['timestamp'].replace('Z', '+00:00')
)
scanner = self.scan_events[src_ip]
scanner['source_ip'] = src_ip
scanner['target_ips'].add(dst_ip)
scanner['target_ports'].add(dst_port)
scanner['alert_count'] += 1
scanner['signatures'][sig] += 1
if 'SYN' in sig:
scanner['scan_types'].add('SYN 扫描')
elif 'FIN' in sig:
scanner['scan_types'].add('FIN 扫描')
elif 'Xmas' in sig:
scanner['scan_types'].add('Xmas 扫描')
elif 'NULL' in sig:
scanner['scan_types'].add('NULL 扫描')
elif 'UDP' in sig:
scanner['scan_types'].add('UDP 扫描')
elif 'Nmap' in sig:
scanner['scan_types'].add('检测到 Nmap')
elif 'Masscan' in sig:
scanner['scan_types'].add('检测到 Masscan')
elif 'Internal' in sig:
scanner['scan_types'].add('内部扫描')
if scanner['first_seen'] is None or ts < scanner['first_seen']:
scanner['first_seen'] = ts
if scanner['last_seen'] is None or ts > scanner['last_seen']:
scanner['last_seen'] = ts
except (json.JSONDecodeError, KeyError, ValueError):
continue
def generate_report(self):
"""生成扫描检测报告。"""
scanners = sorted(
self.scan_events.values(),
key=lambda x: x['alert_count'],
reverse=True
)
print(f"\n{'='*70}")
print("网络扫描检测报告")
print(f"{'='*70}")
print(f"唯一扫描来源:{len(scanners)}\n")
for scanner in scanners:
targets = len(scanner['target_ips'])
ports = len(scanner['target_ports'])
duration = (scanner['last_seen'] - scanner['first_seen']).total_seconds() \
if scanner['first_seen'] and scanner['last_seen'] else 0
is_internal = scanner['source_ip'].startswith(('10.', '172.', '192.168.'))
severity = "严重" if is_internal else \
"高" if targets > 50 or ports > 100 else "中"
print(f"[{severity}] 扫描源:{scanner['source_ip']}")
print(f" 类型:{'内部' if is_internal else '外部'}")
print(f" 扫描类型:{', '.join(scanner['scan_types'])}")
print(f" 目标主机数:{targets},目标端口数:{ports}")
print(f" 告警总数:{scanner['alert_count']}")
print(f" 持续时间:{duration:.0f} 秒")
print(f" 首次发现:{scanner['first_seen']}")
print(f" 主要签名:")
for sig, count in sorted(
scanner['signatures'].items(), key=lambda x: x[1], reverse=True
)[:5]:
print(f" - {sig}:{count}")
print()
if __name__ == '__main__':
detector = ScanDetector()
log_file = sys.argv[1] if len(sys.argv) > 1 else '/var/log/suricata/eve.json'
detector.process_eve_json(log_file)
detector.generate_report()
npx claudepluginhub killvxk/cybersecurity-skills-zhDetects network reconnaissance and port scanning using Suricata/Snort IDS signatures, threshold rules, and traffic anomaly analysis. Useful for SOC analysts investigating scanning activity or validating detection coverage.
Detects network reconnaissance and port scanning using Suricata/Snort IDS signatures, threshold rules, and traffic anomaly analysis. Useful for SOC analysts investigating scanning activity or validating detection coverage.
Detects network reconnaissance and port scanning using Suricata and Snort IDS signatures, threshold-based rules, and traffic anomaly analysis for Nmap, Masscan, and custom scanners.