Python灰帽——Scapy模块 / 数据包的构造、发送、接收、捕获
gjl_ 2024-06-11 14:35:03 阅读 89
Scapy 库
基础
" 网络神器 " scapy
是 python 的一个第三方模块,能够发送、捕获、分析和铸造网络数据包
主要功能:扫描、识别、测试、攻击、包铸造、抓包分析
数据包的构造
在编辑器导入 scapy 包
from scapy.all import *from scapy.layers.inet import *
简单构造
pkt = IP()/TCP()# 该包的结构包含 IP 部分和 TCP 部分
构造数据包
pkt = IP(src="10.9.47.66",dst="10.6.47.88")/TCP()
Scapy 中的分层结构
OSI 模型中的下层协议在前,以/
隔开
Ether()/IP()/TCP()
Ether 类用于设置发送方和接收方的 MAC 地址
构造 HTTP、ICMP 包
pkt=IP()/TCP()/"GET / HTTP1.0\r\n\r\n"
pkt=IP(dst="192.168.147.215")/ICMP()res=sr1(pkt)res.show()
数据包的查看
查看数据包内容
pkt=IP()/TCP()pkt.show()
显示的内容
###[ IP ]### version = 4 ihl = None tos = 0x0 len = None id = 1 flags = frag = 0 ttl = 64 proto = tcp chksum = None src = 127.0.0.1 dst = 127.0.0.1 \options \###[ TCP ]### sport = ftp_data dport = http seq = 0 ack = 0 dataofs = None reserved = 0 flags = S window = 8192 chksum = None urgptr = 0 options = ''
查看数据包格式
pkt=IP()/TCP()ls(pkt)
显示的内容
version : BitField (4 bits) = 4 ('4')ihl : BitField (4 bits) = None ('None')tos : XByteField = 0 ('0')len : ShortField = None ('None')id : ShortField = 1 ('1')flags : FlagsField = <Flag 0 ()> ('<Flag 0 ()>')frag : BitField (13 bits) = 0 ('0')ttl : ByteField = 64 ('64')proto : ByteEnumField = 6 ('0')chksum : XShortField = None ('None')src : SourceIPField = '127.0.0.1' ('None')dst : DestIPField = '127.0.0.1' ('None')options : PacketListField = [] ('[]')--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 = <Flag 2 (S)> ('<Flag 2 (S)>')window : ShortField = 8192 ('8192')chksum : XShortField = None ('None')urgptr : ShortField = 0 ('0')options : TCPOptionsField = [] ("b''")
数据包的发送
总览
发送数据包的函数 | 说明 |
---|---|
sr(pkt) | 发送数据包,接收所有返回包 返回值时两个列表,第一个列表包含收到了应答的数据包和对应的数据包 第二个列表包含未收到应答的数据包 |
sr1(pkt) | 发送数据包,接收一个返回包 |
send(pkt) | 发送数据包,不等待返回包 |
srp(pkt) | 发送2 层数据包,等待回应 |
sendp(pkt) | 发送2 层数据包,不等待返回包 |
数据包的发送
sr()
from scapy.all import *from scapy.layers.inet import *pkt=IP(dst="192.168.147.215")/ICMP()res,unres=sr(pkt)res.summary()# 接收到应答包的数据包和返回包保存到了 res 列表中,使用 res.summary() 可查看两个数据包中的内容# 未接收到应答的数据包保存到 unres 列表中
send()
from scapy.all import *from scapy.layers.inet import *pkt=IP(dst="192.168.147.215")/ICMP()print(pkt.summary())send(pkt)
二层数据包的发送(MAC 地址作为目标)
from scapy.all import *from scapy.layers.inet import *pkt=Ether(dst="ff:ff:ff:ff:ff:ff")print(pkt.summary())sendp(pkt)
数据包的接收
查看响应包
res.show()
from scapy.all import *from scapy.layers.inet import *pkt=IP(dst="192.168.147.215")/ICMP()res=sr1(pkt)res.show()
响应状态
res.type
(回复的 ICMP 数据包的类型编号及含义)
类型(十进制) | 内容 |
---|---|
0 | 回送应答 |
3 | 目标不可达 |
4 | 原点抑制 |
5 | 重定向或改变路由 |
8 | 回送请求 |
9 | 路由器公告 |
10 | 路由器请求 |
11 | 超时 |
17 | 地址子网请求 |
18 | 地址子网应答 |
常用函数
总览
函数名 | 用途 |
---|---|
lsc() | 查看常用函数及其使用方法 |
raw() | 以字节格式显示数据包内容
|
hexdump() | 以十六进制数据表示数据包中的内容
|
summary() | 使用不超过一行的摘要内容来简单描述数据包
|
show() | 显示数据包的详细信息
|
show2() | 相比于 show() 增加了显示数据包的校验和 |
command() | 显示出构造该数据包的命令
|
wrpcap() | 将数据包存储在文件中
|
rdpcap() | 读取 .cap 文件中的数据包(注意格式为列表)
|
raw()
pkt=IP()/TCP()print(raw(pkt))
hexdump()
pkt=IP()/TCP()print(hexdump(pkt))
summary()
pkt=IP()/TCP()print(pkt.summary())
command()
pkt=IP(src="192.168.147.238",dst="192.168.147.215")res=sr1(pkt)print(res.command())
数据包文件的存储、读取
使用wrpcap()
函数存储时,可以将多个 pkt 使用存储为一个列表
使用rdpcap()
函数读取数据包时注意为列表格式
from scapy.all import *from scapy.layers.inet import *# IP(src="192.168.147.238",dst="192.168.147.215")pkt1=IP(src="192.168.147.238",dst="192.168.147.215")/TCP()pkt2=IP()/ICMP()pkts=[pkt1,pkt2]# 将数据包列表 pkts 存储在文件中wrpcap("temp.cap",pkts)# 读取存储数据包的文件(列表格式)pkt_list=rdpcap("temp.cap")# 第一个数据包的摘要print(pkt_list[0].summary())# 第二个数据包的详细数据print(pkt_list[1].show())
sinff() 捕获数据包
参数
参数名 | 含义 |
---|---|
filter | 指定捕获数据包的过滤条件,例如指定捕获特定端口、特定协议等 如 |
iface | 指定要使用的网卡,默认为第一个网卡 |
prn | 指定一个回调函数,用于处理捕获到的每个数据包 |
count | 指定捕获的数据包数量 |
filter
采用伯克利包过滤机制
限定符 | 解释 |
---|---|
Type | 表示指代的对象 如 IP 地址(host)、子网(net)或端口P(port)等 默认为 host |
Dir | 表示数据包的传输方向 常见 scr(源地址)、dst(目的地址) 默认为 “scr or dst” |
Proto | 便是数据包匹配的协议类型 常见 Ether、IP、TCP、ARP |
过滤语句举例:
host 192.168.1.1dst host 192.168.1.1src port 8080# 以太网(MAC 地址)源地址或者目的地址为 11:22:33:44:55:66ether host 11:22:33:44:55:66# 源 MAC 为 11:22:33:44:55:66 的数据包ether src 11:22:33:44:55:66# 源地址在 192.168.1.0/24 网段的数据包src net 192.168.1.0/24# 还可以使用 and、or、not 组合过滤host 192.168.1.1 and port 8080
使用
from scapy.all import *# 定义一个回调函数,输出数据包的概述def callback(pkt): print(pkt.summary) sniff(filter="icmp and host 192.168.147.215",iface="eth0",prn=callback,count=3)# 过滤 192.168.147.215 的 icmp 报文# 选择监听 eth0 网卡# 指定定义好的回调函数 sniff# 捕获三个数据包
运行后,开始监听
此时,ping 过滤的主机,即可捕获到数据包
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。