scapy的使用

本文详细介绍了如何使用Python的Scapy库进行网络数据包的查看、构造、发送和抓包操作,包括常用函数如Ether(),IP(),TCP(),UDP(),ICMP(),以及如何构造IP数据包、TCP数据包,发送和接收数据,以及使用sniff()进行包捕获和BPF过滤机制的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常用函数

协议类
Ether() 
IP()
TCP()
UDP()
ICMP()

查看数据包,查看类的属性
ls()

显示数据包
raw()  字节格式
hexdump() 16进制表示
pkt.summary() 不超过一行的摘要内容
show() 展开视图
show2() show()+数据包校验和
command() 显示出构造该数据包的命令
wrpcap("temp.cap",pkts) 将pkts中的数据写入temp.cap文件
pkts=rdpcap("temp.cap") 读取数据包文件

发送数据包
send() / sendp()--以mac地址作为目标
发送和接收数据包
sr() / sr1() / srp()-- 以mac地址为目标

抓包
sniff()


构造发往指定ip地址的ip数据包

from  scapy.all import *
from scapy.layers.inet import IP

pkg = IP(dst="192.168.101.1")
print(pkg)
# 查看数据包格式
ls(pkg)

result

192.168.1.235 > 192.168.101.1 ip
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                       = 0               ('0')
chksum     : XShortField                         = None            ('None')
src        : SourceIPField                       = '192.168.1.235' ('None')
dst        : DestIPField                         = '192.168.101.1' ('None')
options    : PacketListField                     = []              ('[]')

进程已结束,退出代码0


使用分层的方式构造数据包

from  scapy.all import *
from scapy.layers.inet import IP, TCP
from scapy.layers.l2 import Ether

pkt = Ether()/IP()/TCP()
ls(pkt)

结果

dst        : DestMACField                        = 'ff:ff:ff:ff:ff:ff' ('None')
src        : SourceMACField                      = '00:00:00:00:00:00' ('None')
type       : XShortEnumField                     = 2048            ('36864')
--
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''")

进程已结束,退出代码0

第一个分割线是ether部分,第二个是ip部分,第三个是tcp部分

构造一个http数据包

from  scapy.all import *
from scapy.layers.inet import IP, TCP
from scapy.layers.l2 import Ether


pkt = IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
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''")
--
load       : StrField                            = b'GET / HTTP/1.0\r\n\r\n' ("b''")

进程已结束,退出代码0

发送和接收数据包

send() 方法

  • 构造数据包 pkg = IP()/ICMP()
  • send(pkg)
pkt = IP(dst="192.168.1.235")/ICMP()
send(pkt)

–发送成功

.
Sent 1 packets.

sendp()方法 – 以MAC地址作为目标

pkt = Ether(dst="ff:ff:ff:ff:ff:ff:ff")
sendp(pkt)

send() / sendp()函数的特点 – 只发不收, 只会将数据包发送出去,但不会处理对应的应答数据包


用于发送和接收数据包的函数 sr() ---- sendrecv()
sr() / sr1() / srp()

pkt = IP(dst="127.0.0.1")/ICMP()
ans, uns = sr(pkt)
ans.summary()

使用ans, uns 列表接收sr()的返回值
发送的数据包和接收的数据包都被保存在了ans列表中
uns保存的是未收到响应的数据包。这里没有指定超时参数,如果没有收到响应, uns将包含发送的所有数据包

sr1()作用与sr()基本一样, 但是只返回应答数据包,所以仅使用ans就可以保存返回值了

抓包函数

sniff()

sniff(filter="", iface="any", prn=function, count=N)
  • filter用于对数据包过滤 – 指定只捕获与192.168.1.1的数据包
    sniff(filter=" host 192.168.1.1 ")
  • iface指定使用的网卡, 默认为第一块网卡
  • prn表示对捕获的数据包进行处理的函数,可以使用lambda表达式
    sniff(filter="icmp",prn=lambda x:x.summary())
def packet_callback(pkt):
    print(pkt.summary())

sniff(prn=packet_callback)
  • count用于指定监听数据包的数量

其中filter参数中的过滤机制为BPF – 伯克利包过滤
包含如下限定符

  • type: 表示指代的对象, 如ip地址、子网、端口等 。 常见为host(表示ip,主机名), src(子网), port(端口)
  • dir : 表示数据包传输的方向, 如 src(源地址) , dst(目的地址) , 如果没有指定,默认为 src or dst
  • proto : 表示匹配的协议类型 , 如 Ether, IP, TCP, ARP

可以使用 and / or / not 把多个原语组成一个更复杂的过滤语句
常见原语如下

host 127.0.0.1
dst host 127.0.0.1
src host 127.0.0.1
ether host 11:22:33:44:55:66
ether dst 11:22:33:44:55:66
ether src 11:22:33:44:55:66
dst net 192.168.1.0/24
src net 192.168.1.0/24
net 192.168.1.0/24
dst port 8080
src port 8080
port 8080
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值