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

本文介绍了Python的Scapy库,一个强大的网络数据包操作工具,涵盖了包的构造(包括IP/TCP/HTTP/ICMP等)、分层结构、发送与接收函数,以及如何使用伯克利包过滤机制进行数据包捕获。
摘要由CSDN通过智能技术生成

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.1

dst host  192.168.1.1

src port 8080

# 以太网(MAC 地址)源地址或者目的地址为 11:22:33:44:55:66
ether 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

  • 23
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gjl_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值