Python中Scapy网络嗅探模块的使用

摘要:
目录Scapyscapy的安装和使用发包发包和收包抓包将抓取到的数据包保存查看抓取到的数据包格式化输出过滤抓包Scapyscapy是python中一个可用于网络嗅探的非常强大的第三方库,可以用它来做packet嗅探和伪造packet。scapy已经在内部实现了大量的网络协议。换言之,Scapy是一个强大的操纵报文的交互程序。

目录

Scapy

scapy的安装和使用

发包

发包和收包

抓包

将抓取到的数据包保存

查看抓取到的数据包

格式化输出

过滤抓包


Scapy

scapy是python中一个可用于网络嗅探的非常强大的第三方库,可以用它来做 packet 嗅探和伪造 packet。scapy已经在内部实现了大量的网络协议。如DNS、ARP、IP、TCP、UDP等等,可以用它来编写非常灵活实用的工具。

换言之,Scapy是一个强大的操纵报文的交互程序。它可以伪造或者解析多种协议的报文,还具有发送、捕获、匹配请求和响应这些报文以及更多的功能。Scapy可以轻松地做到像扫描(scanning)、路由跟踪(tracerouting)、探测(probing)、单元测试(unit tests)、攻击(attacks)和发现网络(network discorvery)这样的传统任务。它可以代替 hping 、arpspoof 、arp-sk、arping,p0f甚至是部分的Namp、tcpdump 和 tshark 的功能。

最简单的一个发包

from scapy.all import *
data='hello,word!'
pkt=IP(src='http://t.zoukankan.com/10.96.10.208',dst='10.96.10.209')/TCP(sport=12345,dport=12345)/data
send(pkt,inter=1,count=5)  #每隔一秒发包,发5次

Python中Scapy网络嗅探模块的使用第1张

scapy的安装和使用

scapy默认是不安装的,安装命令:pip install scapy

安装完后:

  • ls() 命令可以查看所有支持的协议
  • ls(IP)命令列出ip协议头部字段格式,只要想查看哪个协议的参数,括号里就填哪个协议
  • IP().show() 列出ip包的信息
  • lsc()命令列出scapy的所有命令
  • conf命令列出scapy的配置参数

发包的包格式:层的协议(参数)/上一层的协议(参数)/要发送的数据 ,比如如下

IP(src='http://t.zoukankan.com/10.96.10.208',dst='10.96.10.209')/TCP(sport=12345,dport=12345)/data

发包

发送三层包:send(pkt, inter=0, loop=0, count=1, iface=N)
发送二层包:sendp(pkt, inter=0, loop=0, count=1, iface=N)
使用tcpreplay在第二层以更快的速度发送数据包 :sendpfast(pkt, pps=N, mbps=N, loop=0, iface=N)

def send(x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, socket=None,*args,**kargs)

def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, realtime=None,
return_packets=False, socket=None,*args,**kargs)

def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, file_cache=False, iface=None,*args,**kargs)

from scapy.all import *
send(IP(dst="202.99.96.68")/UDP(dport=53))
sendp(Ether()/IP(dst="202.99.96.68")/UDP(dport=53))

发包和收包

和上面发包不同的是,发包仅仅是发送包,而发包和收包是对发包的回复信息进行收集。

  • 三层发包和收包:sr(pkt, filter=N, iface=N)
  • 二层发包和收包:srp(pkt, filter=N, iface=N)
  • 三层发包但是仅仅接受第一个回复:sr1(pkt, inter=0, loop=0, count=1, iface=N),
  • 二层发包但是仅仅接受第一个回复:srp1(pkt, filter=N, iface=N)
  • 在环回口发包并且打印出所有的回复:srloop(pkt, timeout=N, count=N), srploop(…)

def sr(x, promisc=None, filter=None, iface=None, nofilter=0,*args,**kargs)

def srp(x, promisc=None, iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL,*args,**kargs)

def sr1(x, promisc=None, filter=None, iface=None, nofilter=0,*args,**kargs)

def srp1(*args,**kargs)

以上所有的发包和收包都是接收到两个参数,第一个参数是回复的包,第二个参数是没回复的包

举例,我们利用arp协议获得指定ip的mac地址

>>ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="10.96.10.197"))
>>print(ans)
>>print(unans)
<Results: TCP:0 UDP:0 ICMP:0 Other:1>
<Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>

可知,ans是回复我们的包,如果我们想获得ans回复的数据,我们可以查看ans的第一个包
>>print(ans[0])
(<Ether  dst=ff:ff:ff:ff:ff:ff type=0x806 |<ARP  pdst=10.96.10.197 |>>, <Ether  dst=50:7b:9d:12:b2:ca src=e4:35:c8:7a:58:a6 type=0x806 |<ARP  hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=e4:35:c8:7a:58:a6 psrc=10.96.10.197 hwdst=50:7b:9d:12:b2:ca pdst=10.96.10.208 |<Padding  load='x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00' |>>>)

ans[0]包中是一个元组,第一部分是我们发的信息,第二部分是回复的信息。很明显,第二部分才是我们要的内容
>>for snd,rcv in ans:
>>   list_mac=rcv.sprintf("%Ether.src% - %ARP.psrc%")     #按照指定格式打印出我们的包
>>   print(list_mac)
e4:35:c8:7a:58:a6 - 10.96.10.197

抓包

scapy抓包使用 sniff() 函数,这个函数有很多参数

def sniff(count=0, store=1, offline=None, prn=None,filter=None, L2socket=None, timeout=None, opened_socket=None, stop_filter=None, iface=None,*args,**kargs)

  • count:抓包的数量,0表示无限制;
  • store:保存抓取的数据包或者丢弃,1保存,0丢弃
  • offline:从 pcap 文件读取数据包,而不进行嗅探,默认为None
  • prn:为每一个数据包定义一个函数,如果返回了什么,则显示。例如:prn = lambda x: x.summary(); ( packct.summar()函数返回的是对包的统计性信息 )
  • filter:过滤规则,使用wireshark里面的过滤语法
  • L2socket:使用给定的 L2socket
  • timeout:在给定的时间后停止嗅探,默认为 None
  • opened_socket:对指定的对象使用 .recv() 进行读取;
  • stop_filter:定义一个函数,决定在抓到指定数据包后停止抓包,如:stop_filter = lambda x: x.haslayer(TCP);
  • iface:指定抓包的接口

将抓取到的数据包保存

from scapy.all import *
package=sniff(iface='eth0',count=10)  #扫描eth0网卡的数据包,总数为10个
wrpcap("test.pcap",package)  #将抓取到的包保存为test.pcap文件

如果我们以后想查看这个包的话,可以这样使用
package = sniff(offline='test.pcap')  或 package= rdpcap('test.pcap')

查看抓取到的数据包

>>from scapy.all import *
>>package=sniff(iface='eth0',count=10)  #扫描eth0网卡的数据包,总数为10个
>>print(package)
<Sniffed: TCP:0 UDP:10 ICMP:0 Other:0>

从上面可以看到,我们抓取到了十个UDP的数据包,然后我们可以查看第一个数据包:package[0]是查看第一个数据包的数据,package[0].show()是查看第一个数据包的详细信息,scapy是按照按照 TCP/IP 四层参考模型显示详细包信息的,即:链路层 [Ethernet]、网络层[IP]、传输层[TCP/UDP]、应用层[RAW] 。我们还可以通过协议来查看指定的包:

package[UDP][0].show() ,因为我们这里只有UDP的数据包,所以就没有这样使用。,而我们也可以直接只获取指定层的数据,如:pcap[UDP][1][Ether].dst 这个包里面是等于ff:ff:ff:ff:ff:ff

from scapy.all import *
package=sniff(iface='eth0',count=10)  #扫描eth0网卡的数据包,总数为10个
print(package)
print(package[0])   #查看第一个数据包的数据
print(package[0].show())  #查看第一个数据包的详情 
######################################################################
<Sniffed: TCP:0 UDP:9 ICMP:0 Other:1>

b"xffxffxffxffxffxffxc8[vxec5xedx08x00Ex00x01#8Gx00x00@x11x17=
`
x88
`
xffxd6x83xd6x83x01x0fNxa0x00qu-PCx00x00Hxb6x1dx07x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xe0x1dFx02x00x00x00x00xd0xb5x1dx07x00x00x00x003'x00x00x00x00x00x00xd0x1dFx02x00x00x00x00xc02xc5x05x00x00x00x00|jx85`x00x00x00x00pxa4/ax00x00x00x00xf9xb9x1dx07x00x00x00x00x00x00x00x00x00x00x00x00`xfexccx05x00x00x00x00Dxb6x1dx07x00x00x00x00`xb6x1dx07x00x00x00x00Hxaa {efdced0c-1ada-40e0-a13e-2968030599d4}x00x00x00x00x00x00x00x01x00x00x00x00x00x00x00@xb6x1dx07x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00nx00xc5xac"

###[ Ethernet ]### 
  dst       = ff:ff:ff:ff:ff:ff
  src       = c8:5b:76:ec:35:ed
  type      = 0x800
###[ IP ]### 
     version   = 4
     ihl       = 5
     tos       = 0x0
     len       = 291
     id        = 14407
     flags     = 
     frag      = 0
     ttl       = 64
     proto     = udp
     chksum    = 0x173d
     src       = 10.96.10.136
     dst       = 10.96.10.255
     options   
###[ UDP ]### 
        sport     = 54915
        dport     = 54915
        len       = 271
        chksum    = 0x4ea0
###[ Raw ]### 
           load      = "x00qu-PCx00x00Hxb6x1dx07x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xe0x1dFx02x00x00x00x00xd0xb5x1dx07x00x00x00x003'x00x00x00x00x00x00xd0x1dFx02x00x00x00x00xc02xc5x05x00x00x00x00|jx85`x00x00x00x00pxa4/ax00x00x00x00xf9xb9x1dx07x00x00x00x00x00x00x00x00x00x00x00x00`xfexccx05x00x00x00x00Dxb6x1dx07x00x00x00x00`xb6x1dx07x00x00x00x00Hxaa {efdced0c-1ada-40e0-a13e-2968030599d4}x00x00x00x00x00x00x00x01x00x00x00x00x00x00x00@xb6x1dx07x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00nx00xc5xac"

格式化输出

如果我们要对抓取到的数据包进行格式化输出,我们可以使用packet.sprintf()函数进行格式化输出

sprintf()读数据格式:IP:%IP.src% 代表读取的是IP字段的源地址

比如要读取IP包的源地址和目的地址:IP:%IP.src% -> %IP.dst%

要读取UDP中的源端口和目的端口:UDP:%UDP.sport% -> %UDP.sport%

Python中Scapy网络嗅探模块的使用第2张

过滤抓包

如果我们想抓指定类型的数据包,就需要使用 filter 进行过滤,而 filter 使用的是 Berkeley Packet Filter (BPF)语法,也就是我们在 wireshark 中可以使用的过滤语法

比如说我们只抓取 icmp 的包,并且按照源ip->目的ip的格式打印出来 。我在一直ping百度,下面是抓包的

sniff(filter="icmp",count=5,prn=lambda x : x.sprintf("{IP:%IP.src%-> %IP.dst%}"))

Python中Scapy网络嗅探模块的使用第3张

相关文章:Python脚本扫描给定网段的MAC地址表(scapy或 python-nmap)

免责声明:文章转载自《Python中Scapy网络嗅探模块的使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Spring源码分析:类型转换(一)之PropertyEditor和ConversionServiceC++指针类型间强制转换下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【Python】批量查询-提取站长之家IP批量查询的结果加强版本v3.0

1、工具说明 写报告的时候为了细致性,要把IP地址对应的地区给整理出来。500多条IP地址找出对应地区复制粘贴到报告里整了一个上午。 为了下次更好的完成这项重复性很高的工作,所以写了这个小的脚本。 某个项目每次改需求都是这么突然。 应 XX 每天要求各种省份域名统计,再加强下Domain to IP to 地区的脚本。 Domain2ip2locality...

Python实例---基于页面的后台管理[简单版]

后台管理菜单 + 母板[css/content/js] 向后台提交数据[2种]: 1. 模态对话框(数据少操作,且Js复杂):form表单 :优点:简单,前端提交后后台处理完成后直接redirect;缺点:无法显示错误信息Ajax提交 : - 有错误,显示错误;无错误,通过js的 location.relad() 刷新页面- 有错误,显示错误;无错误,自...

Python调用百度OCR识别API实现文字图片识别

先参考:百度ocr识别API文档 ;上面有详细步骤,使用百度账号登录,首次创建新的应用,创建后的应用界面如下: 1.Python环境:Python3.6; 2.安装Python三方库:baidu-aip 3.代码实现,如下实现的是高精度实现方法: from aip import AipOcr def baiduOCR(picfile): # pic...

python操作excel向同一sheet循环追加数据

参考文章:https://blog.csdn.net/sdaujz/article/details/102080900?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-15.nonecase&depth_1-utm_source=dis...

python类(class)中参数self的解释说明

python类(class)中参数self的简单解释 1.self只有在类的方法中才会有,其他函数或方法是不必带self的。 2.在调用时不必传入相应的参数。3.在类的方法中(如__init__),第一参数永远是self,表示创建的类实例本身,而不是类本身。4.可以把对象的各种属性绑定到self。5.self代表当前对象的地址。self能避免非限定调用造成...

Python用27行代码绘制一幅满天星

前言 每一个孩子都像星空中的一颗星星,散发着自己所特有的光芒照亮着整个夜空。今天就带大家用27行Python代码绘制一幅满天星吧。 全局设置 在绘制满天星的过程中要运用到turtle工具,它是Python的标准库,也可以形象的称它为海龟库,它可以描绘绘图的轨迹,操作简单、快捷。首先,我们要做一些有关全局的设置 这一步主要是对turtle的画笔大小、绘...