Python灰帽——Scapy模块 / 数据包的构造、发送、接收、捕获

gjl_ 2024-06-11 14:35:03 阅读 89

Scapy

基础

" 网络神器 " scapy 是 python 的一个第三方模块,能够发送、捕获、分析和铸造网络数据

主要功能:扫描、识别、测试、攻击、包铸造、抓包分析

image-20231030105158832

数据包的构造

在编辑器导入 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()

image-20231030105212462

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 列表中

image-20240124163634441

send()

from scapy.all import *from scapy.layers.inet import *pkt=IP(dst="192.168.147.215")/ICMP()print(pkt.summary())send(pkt)

image-20240124155647332

二层数据包的发送(MAC 地址作为目标)

from scapy.all import *from scapy.layers.inet import *pkt=Ether(dst="ff:ff:ff:ff:ff:ff")print(pkt.summary())sendp(pkt)

image-20240124160013712

数据包的接收

查看响应包

res.show()

from scapy.all import *from scapy.layers.inet import *pkt=IP(dst="192.168.147.215")/ICMP()res=sr1(pkt)res.show()

image-20240124161517876

响应状态

res.type(回复的 ICMP 数据包的类型编号及含义)

类型(十进制) 内容
0 回送应答
3 目标不可达
4 原点抑制
5 重定向或改变路由
8 回送请求
9 路由器公告
10 路由器请求
11 超时
17 地址子网请求
18 地址子网应答

常用函数

总览

函数名 用途
lsc() 查看常用函数及其使用方法
raw() 以字节格式显示数据包内容

raw(pkt)

hexdump() 以十六进制数据表示数据包中的内容

hexdump(pkt)

summary() 使用不超过一行的摘要内容来简单描述数据包

pkt.summary()

show() 显示数据包的详细信息

pkt.show()

show2() 相比于 show() 增加了显示数据包的校验和
command() 显示出构造该数据包的命令

res.command()

wrpcap() 将数据包存储在文件中

wrpcap("tmp.cap",pkts)

rdpcap() 读取 .cap 文件中的数据包(注意格式为列表

pkts=rdpcap(temp.cap)

raw()

pkt=IP()/TCP()print(raw(pkt))

image-20240124141330811

hexdump()

pkt=IP()/TCP()print(hexdump(pkt))

image-20240124141600369

summary()

pkt=IP()/TCP()print(pkt.summary())

image-20240124142129572

command()

pkt=IP(src="192.168.147.238",dst="192.168.147.215")res=sr1(pkt)print(res.command())

image-20240124144446488

数据包文件的存储、读取

使用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())

image-20240124153326277

sinff() 捕获数据

参数

参数名 含义
filter 指定捕获数据包的过滤条件,例如指定捕获特定端口、特定协议等

dst host 192.168.1.1 and port 8080

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# 捕获三个数据

运行后,开始监听

image-20240124150536925

此时,ping 过滤的主机,即可捕获到数据

image-20240124150823770



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。