detecting-network-scanning-with-ids-signatures
使用 Suricata 和 Snort IDS 签名、基于阈值的检测规则和流量异常分析,检测网络侦察和端口扫描,识别 Nmap、Masscan 及自定义扫描活动。
Best use case
detecting-network-scanning-with-ids-signatures is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
使用 Suricata 和 Snort IDS 签名、基于阈值的检测规则和流量异常分析,检测网络侦察和端口扫描,识别 Nmap、Masscan 及自定义扫描活动。
Teams using detecting-network-scanning-with-ids-signatures should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/detecting-network-scanning-with-ids-signatures/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How detecting-network-scanning-with-ids-signatures Compares
| Feature / Agent | detecting-network-scanning-with-ids-signatures | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
使用 Suricata 和 Snort IDS 签名、基于阈值的检测规则和流量异常分析,检测网络侦察和端口扫描,识别 Nmap、Masscan 及自定义扫描活动。
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 使用 IDS 签名检测网络扫描
## 概述
网络扫描(network scanning)通常是攻击的第一阶段,攻击者使用 Nmap、Masscan、ZMap 和自定义扫描工具枚举活跃主机、开放端口、运行中的服务和操作系统版本。检测这种侦察活动可以为潜在攻击提供早期预警。Suricata 和 Snort 等 IDS/IPS 系统可通过三种方式识别扫描:基于签名的检测(匹配已知扫描工具的数据包模式)、基于阈值的检测(统计一段时间内的连接尝试次数)和异常检测(识别异常流量模式)。本技能涵盖编写和部署用于扫描检测的 IDS 签名、配置基于阈值的告警,以及将扫描活动与下游攻击指标进行关联。
## 前置条件
- 以 IDS/IPS 模式部署 Suricata 7.0+ 或 Snort 3.0+
- 用于流量可见性的网络 TAP 或 SPAN 端口
- 启用 Emerging Threats 规则集
- 用于告警分析的日志基础设施(ELK Stack、Splunk)
- 了解正常网络流量模式的基线知识
## 核心概念
### 扫描技术与检测指标
| 扫描类型 | 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 时序模板
| 模板 | Nmap 参数 | 速度 | 检测难度 |
|----------|-----------|-------|---------------------|
| Paranoid | `-T0` | 每 5 分钟 1 个探测 | 极难 |
| Sneaky | `-T1` | 每 15 秒 1 个探测 | 困难 |
| Polite | `-T2` | 每 0.4 秒 1 个探测 | 中等 |
| Normal | `-T3` | 默认并行度 | 容易 |
| Aggressive | `-T4` | 并行,1.25 秒超时 | 很容易 |
| Insane | `-T5` | 最大并行度 | 极易 |
## 实施步骤
### 步骤 1:部署 Suricata 扫描检测规则
创建 `/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;)
```
### 步骤 2:配置基于阈值的检测
编辑 `/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
```
### 步骤 3:扫描检测分析脚本
```python
#!/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()
```
## 响应剧本
1. **分类(Triage)**——确定扫描是否来自已授权的扫描器或未知来源
2. **信息丰富(Enrich)**——在威胁情报 feeds 中查询源 IP
3. **评估范围**——统计唯一目标和端口数量,评估扫描广度
4. **封锁**——将激进的外部扫描器添加到防火墙封锁列表
5. **调查内部**——内部扫描可能表明主机被入侵;隔离并调查
6. **关联**——检查扫描后是否发生了利用尝试
## 最佳实践
- **将授权扫描器加白名单**——对已知漏洞扫描器 IP 抑制告警
- **重点关注内部扫描**——内部扫描比外部扫描严重性更高(表明已被入侵)
- **阈值调整**——根据环境调整阈值;/16 网络的扫描噪声更多
- **与其他告警关联**——将扫描检测与利用告警结合,获得杀伤链可见性
- **基于时间的分析**——非常规时间(凌晨 3 点)的扫描需优先处理
- **限制告警速率**——防止扫描洪泛使 SIEM 充斥噪声
## 参考资料
- Suricata 规则文档
- Nmap IDS 规避技术
- OPNsense Suricata Nmap 检测规则
- Emerging Threats 规则集Related Skills
scanning-network-with-nmap-advanced
使用 Nmap 的脚本引擎、时序控制、规避技术和输出解析,对授权目标网络执行高级网络侦察, 发现主机、枚举服务、检测漏洞并识别操作系统。
scanning-kubernetes-manifests-with-kubesec
使用 Kubesec 对 Kubernetes 资源清单执行安全风险分析,识别错误配置、权限提升风险以及与安全最佳实践的偏差。
scanning-infrastructure-with-nessus
Tenable Nessus 是业界领先的漏洞扫描器,用于识别网络基础设施(包括服务器、工作站、网络设备和操作系统)中的安全弱点。
scanning-docker-images-with-trivy
Trivy 是 Aqua Security 开源的综合性漏洞扫描器,用于检测容器镜像中操作系统软件包、语言特定依赖项的漏洞、错误配置、密钥和许可证违规,并集成到 CI/CD 流水线,支持 SARIF、CycloneDX 和 SPDX 等多种输出格式。
scanning-containers-with-trivy-in-cicd
本技能涵盖将 Aqua Security 的 Trivy 扫描器集成到 CI/CD 流水线中,用于全面的容器镜像漏洞检测。包括扫描 Docker 镜像中的操作系统包和应用依赖 CVE、检测 Dockerfile 中的错误配置、扫描文件系统和 Git 仓库,以及建立基于严重性的质量门禁以阻止有漏洞的镜像部署。
scanning-container-images-with-grype
使用 Anchore Grype 扫描容器镜像的已知漏洞(Vulnerability),支持基于 SBOM 的匹配和可配置的严重性阈值。
performing-wireless-network-penetration-test
执行无线网络渗透测试,通过捕获握手包、破解 WPA2/WPA3 密钥、检测流氓接入点以及使用 Aircrack-ng 和相关工具测试无线网络分段,评估 WiFi 安全性。
performing-web-application-scanning-with-nikto
Nikto 是一款开源 Web 服务器和 Web 应用程序扫描器,可针对超过 7,000 个潜在危险文件/程序进行测试,检查超过 1,250 个服务器的过期版本,并识别超过 270 个服务器的版本特定问题。
performing-vulnerability-scanning-with-nessus
使用 Tenable Nessus 执行认证和未认证漏洞扫描,识别网络基础设施、服务器和应用程序中的已知漏洞、 错误配置、默认凭据和缺失补丁。扫描器将发现与 CVE 数据库和 CVSS 评分关联,生成优先级修复指导。 适用于漏洞扫描、Nessus 评估、补丁合规检查或自动化漏洞检测等请求场景。
performing-sca-dependency-scanning-with-snyk
本技能涵盖使用 Snyk 实施软件成分分析(SCA, Software Composition Analysis),在 CI/CD 流水线中检测存在漏洞的开源依赖项。内容包括扫描包清单和锁文件、自动修复拉取请求生成、许可证合规检查、已部署应用程序的持续监控,以及与 GitHub、GitLab 和 Jenkins 流水线的集成。
performing-ot-vulnerability-scanning-safely
使用被动监控、原生协议查询和经过精心控制的Tenable OT Security主动扫描,在OT/ICS环境中安全执行漏洞扫描,在不破坏工业过程或导致旧版控制器崩溃的情况下识别漏洞。
performing-ot-network-security-assessment
本技能涵盖对运营技术(OT)网络(包括SCADA系统、DCS架构和工业控制系统通信路径)进行全面安全评估。内容涉及Purdue参考模型各层、识别IT/OT融合风险、评估区域间防火墙规则,以及映射工业协议流量(Modbus、DNP3、OPC UA、EtherNet/IP),以检测关键基础设施中的错误配置、未授权连接和攻击面。