Python Scapy模块详解:从基础命令到高级网络扫描

叶初
叶初
发布时间:2026-10-14| 5人浏览过
原创

本文详细介绍Python中Scapy模块的使用方法,涵盖常用命令、数据包构造(IP、ARP、TCP等)、发包收包技巧、SYN半开式扫描以及数据序列化与离线解析。通过具体代码示例,帮助开发者掌握网络通信底层操作,提升网络安全测试与开发效率。

前言

日常网络浏览涉及大量数据包的发送、接收与处理循环。

本文将解析网络数据包的构成,并介绍Scapy这一强大的发包与收包工具。

数据包(Packet)是网络通信的基本单位,通常包含源地址、目标地址及有效载荷数据。

数据包结构由固定长度的包头和可变长度的包体组成。

了解数据包基础后,接下来介绍Scapy的具体用法。

一、常用命令

1. ls():用于列出所有支持的数据包对象,可带参数查看特定包的详细信息,也可不带参数查看所有。

通过该命令可以查看完整的内容列表。若需深入查看特定模块,例如ARP或TCP,可指定参数进行查询。

注意命令的大小写,例如必须使用ls(ARP)才能获取正确结果,ls(arp)将报错。

2. lsc():用于列出Scapy支持的所有函数。

该命令输出包含大量英文函数名,初学者可能需要一定时间熟悉。

3. hide_defaults():用于隐藏与默认值相同的参数项,简化输出显示。


a=IP()
print(a.hide_defaults())

4. display():用于查看当前数据包各参数的具体取值情况。


a=IP()
a.display()

5. 更多命令:Scapy提供了丰富的辅助命令,如show_interfaces()显示网卡信息,str(pkt)组装数据包,hexdump(pkt)进行十六进制转储,ls(pkt)显示字段值列表,pkt.summary()显示一行摘要,pkt.show()展开视图,pkt.show2()显示聚合数据包(如计算校验和),pkt.sprintf()用字段填充格式字符串,pkt.decode_payload_as()改变负载解码方式,pkt.psdump()绘制PostScript图表,pkt.pdfdump()绘制PDF,pkt.command()返回生成该数据包的Scapy命令,nsummary()规定数量的摘要,conversations()显示会话图表,filter()返回过滤后的数据包列表,hexdump()返回所有数据包的十六进制转储,import_hexcap()将十六进制导入Scapy,make table()根据Lambda函数显示表格,traceroute()查看IP路径,export_object()将数据包转换为Base64编码的Python数据结构,import_object()重新导入输出,save_session()保存会话变量,load_session()读取保存的会话,fuzz()随机更改某些未计算的值(如校验和),但符合字段值范围。


命令                                  作用
show_interfaces()                  显示网卡信息

str(pkt)                            组装数据包

hexdump(pkt)                        十六进制转储

ls(pkt)                          显示出字段值的列表

pkt.summary()                        一行摘要

pkt.show()                      针对数据包的展开视图

pkt.show2()             显示聚合的数据包(例如,计算好了的校验和)

pkt.sprintf()                   用数据包字段填充格式字符串

pkt.decode_payload_as()         改变payload的decode方式

pkt.psdump()                绘制一个解释说明的PostScript图表

pkt.pdfdump()                   绘制一个解释说明的PDF

pkt.command()               返回可以生成数据包的Scapy命令

nsummary()                      同上,但规定了数据包数量

conversations()                     显示一个会话图表

filter()                    返回一个lambda过滤后的数据包列表

hexdump()                       返回所有数据包的一个hexdump

import_hexcap()                 将hexdump重新导入到Scapy中

hexraw()                    返回所有数据包Raw layer的hexdump

padding()                   返回一个带填充的数据包的hexdump

nzpadding()                 返回一个具有非零填充的数据包的hexdump

plot()                      规划一个应用到数据包列表的lambda函数

make table()                    根据lambda函数来显示表格

traceroute("baidu.com")     查看IP路径的traceroute功能

export_object()             数据包转换成base64编码的Python数据结构

import_object()                     可以将输出重新导入

save_session()                  保存所有的session变量

load_session()                  读取保存的session

fuzz()      更改一些默认的不被计算的值(比如校验和checksums),更改的值是随机的,但是是符合字段的值的。

二、嗅探数据包


from scapy.all import *
pkt = sniff(iface = "Realtek PCIe GBE Family Controller",count = 3 ,filter='tcp',prn = lambda x: x.sprintf('{IP:%IP.src%->%IP.dst%\n}{Raw:%Raw.load%\n}'))

filter:过滤条件
iface:网卡接口名称
count:数据包数量
prn:回调函数,通常与lambda搭配使用
sprintf()函数控制输入信息

抓取源地址为192.168.3.3的端口为80的tcp报文:
sniff(filter="ip src 192.168.3.3 and tcp and tcp port 80", prn=lambda x:x.summary())

抓取目的地址网段为192.168.3.3/24的报文:
sniff(filter="dst net 192.168", prn=lambda x:x.summary())

抓取非ICMP的报文:
sniff(filter="not icmp", prn=lambda x:x.summary())


将抓取到的报文的summary打印出来:
sniff(filter="icmp", prn=lambda x:x.summary(), count=10)

将所有IP报文的源地址打印出来:
sniff(filter="icmp", prn=lambda x:x[IP].src, count=10)

三、构造数据包


pkt= Ether()/IP(dst='192.168.1.2')/TCP(dport=80)

涉及网络协议时,需参考OSI七层模型。

OSI 七层网络模型 TCP/IP 四层概念模型 对应网络协议
应用层(Application) 应用层 HTTP、TFTP, FTP, NFS, WAIS、SMTP
表示层(Presentation) 应用层 Telnet, Rlogin, SNMP, Gopher
会话层(Session) 应用层 SMTP, DNS
传输层(Transport) 传输层 TCP, UDP
网络层(Network) 网络层 IP, ICMP, ARP, RARP, AKP, UUCP
数据链路层(Data Link) 数据链路层 FDDI, Ethernet, Arpanet, PDN, SLIP, PPP
物理层(Physical) 数据链路层 IEEE 802.1A, IEEE 802.2到IEEE 802.11

上述表格展示了各网络协议对应的OSI模型层级,接下来介绍具体协议的使用方法。

四、各个协议用法

1. 构造IP包:可通过传入参数创建IP数据包,例如指定目标IP和TTL值。


#构造一个 IP 包,并传入一些参数
pkt = IP(dst="192.168.1.2",ttl=10)
ls(pkt)  
version:版本号
ihl:头长度
tos:服务类型
len:IP数据包总长
id:标识符
flags:标记
flag:片偏移
ttl:生存时间
proto:协议类型
chksum:头部校验
src:源IP地址
dst:目的IP地址
options:可选项

2. 构造ARP包:通过指定操作类型、目标MAC和目的IP来创建ARP请求或响应。


#构造ARP包
ARP(op=1, hwdst="ff:ff:ff:ff:ff:ff", pdst=ip_address)
#arp类的构造函数列表:
ls(ARP)
hwtype     : XShortField          = (1)  值为1表示以太网地址,其它还可能表示令牌环地址
ptype      : XShortEnumField      = (2048)  0x0800表示IP地址,其它还可能是ICMP/IGMP
hwlen      : ByteField            = (6)   ARP报文中,它的值为6
plen       : ByteField            = (4)  ARP报文中,它的值为4
op         : ShortEnumField       = (1) 取值为1或者2,代表ARP请求或者响应包。1.ARP请求,2.ARP应答,3.RARP请求,4.RARP应答
 
hwsrc      : ARPSourceMACField    = (None) 发送方Mac地址。
psrc       : SourceIPField        = (None) 发送方IP地址。
hwdst      : MACField             = ('00:00:00:00:00:00') 目标Mac地址。
pdst       : IPField              = ('0.0.0.0') 目标IP地址。

3. 构造Ether包:创建以太网帧,通常需指定目的和源MAC地址,若不指定则默认为广播地址ff:ff:ff:ff:ff:ff。


#构造Ether
Ether(dst="ff:ff:ff:ff:ff:ff")
ls(Ether)
dst        : DestMACField         = (None) 目的MAC
src        : SourceMACField       = (None) 源MAC
type       : XShortEnumField      = (36864)
构造一个以太网数据包通常需要指定目标和源MAC地址,如果不指定,默认发出的就是广播包ff:ff:ff:ff:ff:ff

4. 构造TCP包:指定源端口、目的端口、序列号、确认号、标志位(如S表示SYN)、窗口大小等参数。


#构造TCP包
sport      : ShortEnumField                      = 20              (20) 目标端口
dport      : ShortEnumField                      = 80              (80)  源端口
seq        : IntField                            = 0               (0)
ack        : IntField                            = 0               (0)
dataofs    : BitField (4 bits)                   = None            (None)
reserved   : BitField (3 bits)                   = 0               (0)
flags      : FlagsField (9 bits)                 = <Flag 2 (S)>    (<Flag 2 (S)>)
window     : ShortField                          = 8192            (8192)
chksum     : XShortField                         = None            (None)
urgptr     : ShortField                          = 0               (0)
options    : TCPOptionsField                     = []              (b'')

五、发包,收包

Scapy提供两种主要模式:只发不收,以及发包且收包。

1. 只发不收:使用send()在第三层发包,或sendp()在第二层发包,均无接收功能。


send(pkt, inter=0, loop=0, count=1, iface=N) 
pkt:数据包
inter:发包间隔时间
count:发包数量
iface:网卡接口名称

send(),在第三层发包,没有接收功能;send(IP(dst="www.baidu.com",ttl=2)/ICMP())

sendp(),在第二层发包,没有接收功能。sr(Ether()/IP(dst=www.baidu.com))

2. 发包且收包:使用sr()或sr1()在第三层发包并接收回复,sr1仅接收第一个回复;使用srp()或srp1()在第二层发包并接收回复。


sr()和sr1()都是在第三层发包,sr1表示只接收第一个回复。

sr(IP(dst="www.baidu.com",ttl=(1,4))/TCP(dport=[21,23,80],flags="S")) 返回两个值

sr1(IP(dst="www.baidu.com",ttl=(1,4))/ICMP()) 

srloop(IP(dst="www.baidu.com",ttl=1)/ICMP()) #不停的ping百度

srloop(IP(dst="www.baidu.com",ttl=1)/ICMP(),inter=3,count=2) #每隔3秒ping一次,一共执行两次

#inter表示间隔,count记录次数

srp()和srp1()都是根据第二层发包,srp1表示只接收第一个回复
srp(Ether()/IP(dst="www.baidu.com"))
srp1(Ether()/IP(dst=www.baidu.com))

六、SYN半开式扫描

当TCP连接指定端口时,若flags参数设为S(SYN),则执行半开式扫描。若端口监听,返回syn/ack;否则返回rst/ack。


sr1(IP(dst="192.168.1.2")/TCP(dport=80,flags="S"))

七、数据包序列化,反序列化

序列化:使用wrpcap()将数据包对象保存为pcap文件。

反序列化:使用rdpcap()读取pcap文件内容。


pkt= Ether()/IP(dst='192.168.1.2')/TCP(dport=80)
#将嗅探到的数据包内容写到pcap文件中 
wrpcap("hw.pcap",pkt)

#读取pcap文件。
read=rdpcap('hw.pcap')
print(read[1])#打印嗅探到的包的数据

八、数据包与字符串转换

通过str()将数据包转换为字符串,或使用Ether()等构造函数从字符串还原数据包,便于直观分析。


zfc= str(pkts[0]) 
z= Ether(zfc)

九、导入导出 base64 编码

使用export_object()导出数据包为Base64编码字符串,利用import_object()重新导入,这是一种数据加密与传输方式。


export_object(str(pkts[0])) 导出数据包
new_Pkt = import_object() #将上一步导出的字符串填入

十、离线数据包的解析

在未联网环境下,可通过离线文件解析数据包。

使用sniff(offline="hw.pcap")即可对捕获的离线数据包进行分析。


sniff(offline = "hw.pcap")#离线数据包

总结

Scapy功能强大,通过少量命令即可实现复杂的发包收包操作,显著节省开发时间。

深入学习其命令可发现更多实用功能,但请确保仅用于合法的技术研究与开发。

以上就是关于Python使用scapy模块发包收包的详细内容,更多相关技术文章请关注本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。