Scapy是一款基于Python的交互式数据包操作工具,能够构造、发送、捕获和分析网络协议数据包。其核心特点包括:
Scapy工作流程
sudo apt update
sudo apt install scapy -y
sudo yum install epel-release
sudo yum install scapy
pip3 install --user scapy
Scapy依赖关系
# 普通用户模式(功能受限)
scapy
# 特权模式(推荐)
sudo scapy
>>> conf # 查看全局配置
>>> ls() # 列出所有协议
>>> lsc() # 查看可用命令
核心命令使用分布
# 构建ICMP包(完整写法)
eth = Ether(src="00:11:22:33:44:55", dst="ff:ff:ff:ff:ff:ff")
ip = IP(src="192.168.1.100", dst="8.8.8.8", ttl=64)
icmp = ICMP(type=8, code=0)
packet = eth/ip/icmp
图3-3:协议分层结构类图
函数 | 作用层级 | 是否需要root | 典型场景 |
---|---|---|---|
send() |
网络层 | 是 | 发送IP/UDP/ICMP |
sendp() |
链路层 | 是 | 发送Ether/ARP |
sr() |
网络层 | 是 | 发送并接收响应 |
srp() |
链路层 | 是 | 发送二层包并响应 |
# 发送ICMP请求(自动完成路由选择)
send(IP(dst="8.8.8.8")/ICMP())
# 发送ARP广播(指定网卡)
sendp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), iface="eth0")
# 捕获10个TCP端口80的数据包
pkts = sniff(filter="tcp port 80", count=10)
# 实时显示HTTP流量
sniff(prn=lambda x: x.summary(), lfilter=lambda x: TCP in x and x[TCP].dport == 80)
抓包过滤流程
pkt = pkts[0]
# 查看各层字段
pkt.show()
# 提取特定字段
print(f"源MAC: {pkt[Ether].src}")
print(f"TTL值: {pkt[IP].ttl}")
# 十六进制转储
hexdump(pkt)
格式 | 命令 | 特点 |
---|---|---|
.pcap | wrpcap() |
Wireshark兼容格式 |
.pcapng | wrpcap() |
支持元数据存储 |
文本 | str(pkt) |
可读性高但无法重载 |
# 保存捕获数据
wrpcap("http.pcap", pkts)
# 读取数据包文件
pkts = rdpcap("http.pcap")
数据包篡改回放流程
# 生成ICMP洪水攻击测试流量
send(IP(dst="192.168.1.1")/ICMP(), loop=1, inter=0.001)
>>> IP(dst="8.8.8.8")/TCP(<TAB自动补全>
dport : 目标端口
sport : 源端口
seq : 序列号
flags : 控制位
# 发送ICMP请求并等待响应
ans, unans = sr(IP(dst="8.8.8.8")/ICMP(), timeout=2)
if ans:
ans[0][1].show()
else:
print("目标不可达!")
res = sr1(IP(dst="192.168.1.1")/TCP(dport=80, flags="S"), timeout=1)
if res and res[TCP].flags == 0x12: # SYN-ACK
send(IP(dst="192.168.1.1")/TCP(dport=80, flags="R")) # 发送RST关闭连接
print("端口开放!")
>>> send(IP(dst="8.8.8.8")/ICMP())
Sent 1 packets.
ICMP包发送流程
from scapy.all import *
# 构建完整HTTP GET请求
eth = Ether(dst="00:0c:29:xx:xx:xx") # 目标MAC
ip = IP(dst="192.168.1.100") # 目标IP
tcp = TCP(dport=80, sport=54321, seq=1000, flags="S") # SYN包
http = "GET /index.html HTTP/1.1\r\nHost: test.com\r\n\r\n"
packet = eth/ip/tcp/http
sendp(packet, iface="eth0")
协议栈构建流程
# 捕获并解析未知协议
pkts = sniff(filter="udp and port 5000", count=5)
pkt = pkts[0]
hexdump(pkt) # 查看原始十六进制
pkt.show() # 自动解析已知字段
from scapy.all import *
arp_table = {}
def arp_monitor(pkt):
if ARP in pkt and pkt[ARP].op == 2: # ARP响应
if arp_table.get(pkt.psrc) != pkt.hwsrc:
print(f"ARP欺骗告警!IP {pkt.psrc} MAC已从 {arp_table.get(pkt.psrc)} 改为 {pkt.hwsrc}")
sniff(filter="arp", prn=arp_monitor, store=0)
ARP欺骗检测状态机
vlan_pkt = Ether()/Dot1Q(vlan=100)/IP(dst="10.0.100.1")/ICMP()
sendp(vlan_pkt, iface="eth0")
VLAN跳跃攻击原理
ans, unans = sr(IP(dst="www.baidu.com", ttl=(1,30))/UDP()/DNS(qd=DNSQR(qname="baidu.com")))
for snd, rcv in ans:
print(f"TTL {snd.ttl} | {rcv.src} | {rcv.time - snd.sent_time:.3f}ms")
网络延迟甘特图
# 全连接扫描(易被日志记录)
ans, unans = sr(IP(dst="192.168.1.1")/TCP(dport=(1,1024), flags="S"))
# 半连接扫描(隐蔽性更强)
ans = srloop(IP(dst="192.168.1.1")/TCP(dport=80, flags="S"), timeout=1, retry=-2)
隐蔽扫描策略
模式 | 发包速率(pps) | CPU占用率 |
---|---|---|
单线程 | 12,000 | 85% |
多线程(4核) | 45,000 | 95% |
sendpfast | 220,000 | 40% |
# 使用sendpfast加速
sendpfast(pkt_stream, pps=100000, iface="eth0", loop=10)
不同加速方案架构
# 跨平台适配代码示例
from scapy.arch import get_windows_if_list
import platform
if platform.system() == "Windows":
print("可用网卡:", get_windows_if_list())
elif platform.system() == "Linux":
print("可用网卡:", get_if_list())
建议在实验环境中验证所有案例,并参考RFC文档深入理解协议细节。希望此文对您有所帮助!