互联网技术 / 互联网资讯 · 2024年1月2日

Scapy基础知识与数据包处理入门

Scapy 是一个非常实用的交互式数据包处理工具,适合用于构造、发送、捕获、解析和匹配各种网络协议数据包。它既能完成常见的网络测试任务,也能胜任一些传统工具不太方便处理的场景,例如协议探测、路由跟踪、扫描、单元测试以及网络发现等。

在很多情况下,Scapy 可以覆盖多种网络工具的部分能力。它的优势在于灵活、可编程,并且适合快速验证网络通信过程中的各种细节。对于学习网络协议、分析报文结构和进行实验性测试来说,它是一个非常高效的选择。

安装 Scapy

如果使用的是 Python 3 环境,通常直接通过 pip 安装即可:

pip3 install scapy

进入 Scapy 交互环境

安装完成后,可以在终端中输入 scapy 进入交互式 Shell。在这个环境里,可以直接构造和操作数据包。

常用查看命令包括:

  • ls():查看支持的协议,或查看某个协议包含的字段参数。
  • lsc():查看可用的内置函数。

发送与接收数据包

send()

send() 用于在第 3 层发送数据包,由 Scapy 自动补齐第 2 层头部,不负责接收返回数据。

常见参数:

  • count:指定发送次数。
  • loop:循环发送,直到手动中断。
  • inter:设置每次发送之间的间隔时间。

示例:

send(IP(dst='8.8.8.8')/TCP(dport=53, flags='S'))

send(IP(dst='8.8.8.8')/TCP(dport=53, flags='S'), count=10)

send(IP(dst='8.8.8.8')/TCP(dport=53, flags='S'), loop=1)

sendp()

sendp()send() 类似,但工作在第 2 层,因此需要显式提供链路层头部。它适合在指定网卡上直接发送以太网帧。

示例:

sendp(Ether()/IP(dst='1.2.3.4', ttl=(1,4)), iface='eth0')

sendp("I'm travelling on Ethernet", iface='eth0', loop=1, inter=0.2)

sendp(rdpcap('/tmp/pcapfile'))

sr()

sr() 用于发送数据包并接收响应,返回两个结果集:一个是已收到响应的数据包,另一个是没有收到响应的数据包。

示例:

sr(IP(dst='60.205.177.168')/TCP(dport=[21,22,23]))

通常可以这样获取结果:

ans, unans = sr(IP(dst='60.205.177.168')/TCP(dport=[21,22,23]))

unans.summary()

sr1()

sr1() 会发送数据包,并只返回接收到的第一个响应结果。适合只关心单个回复的场景。

示例:

p = sr1(IP(dst='www.baidu.com')/ICMP()/"asdqwe")

srloop()

srloop() 用于循环发送数据包,并持续显示收到的响应。这个函数适合观察目标主机在连续请求下的回应情况。

示例:

packet = IP(dst='60.205.177.168')/ICMP()

srloop(packet)

使用 Scapy 创建数据包

Scapy 的数据包构造方式遵循网络协议分层思想。每一层都是一个独立对象,完整的数据包则通过把这些层依次叠加形成。

它会根据 TCP/IP 各层协议头的定义来组织报文,因此既适合快速构造简单数据包,也适合做更精细的字段控制。

一行构造数据包

可以直接使用一行语句完成多层封装:

packet = Ether()/IP(dst='8.8.8.8')/TCP(dport=53, flags='S')

分层构造后再组合

也可以先分别创建各层,再通过 / 运算符进行堆叠:

l2 = Ether()

l3 = IP(dst='8.8.8.8/30')

l4 = TCP(dport=53, flags='S')

packet = l2/l3/l4

Scapy 支持的 IP 写法

Scapy 对目标地址的写法支持比较灵活,既可以使用普通 IP,也可以使用 CIDR 表示法,甚至可以直接使用主机名。

示例:

packet = IP(dst='8.8.8.8')

packet = IP(dst='scanme.nmap.org')

packet = IP(dst='8.8.8.8/30')

packet = IP(dst='egadz.metasploit.com/30')

这意味着它不仅能描述单个目标,还能生成一个地址集合,方便用于批量测试。

创建一组数据包

Scapy 可以通过字段取值范围或列表,自动生成一组数据包。这样在做扫描或参数组合测试时会非常方便。

例如:

pkts = IP(ttl=[1,3,5,(7,10)])/TCP()

packet = IP(dst='192.168.*.1-10')/TCP(dport=(0,100))

通过这种方式,可以一次性生成多个不同 TTL、目标地址或端口的数据包,减少重复编写代码的工作量。

检查数据包结构

在构造好数据包后,可以用 ls() 查看其字段详情以及对应的数据类型。这对于理解报文结构和调试字段设置非常有帮助。

示例:

packet = IP()/TCP()

ls(packet)

执行后会显示该数据包中各字段的名称、类型及默认值,例如 IP 头中的 versionihltoslen 等。

总结

Scapy 的核心价值在于“可编程的数据包处理”。它既可以作为学习网络协议的实验工具,也可以作为实际测试中的灵活组件。掌握安装、交互环境、收发函数以及分层构造报文的方法后,就可以逐步开展更深入的网络分析与自动化测试工作。