首页 > 其他分享 >scapy模块基础使用

scapy模块基础使用

时间:2023-04-02 16:14:43浏览次数:32  
标签:8.1 IP 报文 scapy 基础 192.168 TCP 模块 dst

一、安装scapy:

完整安装,会安装ipython和scapy等模块,命令如下:

pip install --pre scapy[complete]

 

python导入scapy使用下面语句:

from scapy.all import *

 

一些工具、方法和用途:
summary() 显示一个关于每个数据包的摘要列表
nsummary() 同上,但规定了数据包数量
conversations() 显示一个会话图表
show() 显示首选表示(通常用nsummary())
filter() 返回一个lambda过滤后的数据包列表
hexdump() 返回所有数据包的一个hexdump
hexraw() 返回所以数据包Raw layer的hexdump
padding() 返回一个带填充的数据包的hexdump
nzpadding() 返回一个具有非零填充的数据包的hexdump
plot() 规划一个应用到数据包列表的lambda函数
make table() 根据lambda函数来显示表格

Route()  实例Route类,返回本机路由表

Route6()  实例化Route6类,返回本机v6路由表

arping 模拟arping函数

 

查看到目标ip的路由,返回出口网卡名、本机ip、网关ip的元组:

>>> help(Route().route)
Help on method route in module scapy.route:

route(dst=None, verbose=2) method of scapy.route.Route instance
Returns the IPv4 routes to a host.
parameters:
- dst: the IPv4 of the destination host

returns: (iface, output_ip, gateway_ip)
- iface: the interface used to connect to the host
- output_ip: the outgoing IP that will be used
- gateway_ip: the gateway IP that will be used

>>>

>>> Route().route('www.baidu.com')
('\\Device\\NPF_{C441126F-2ECC-4D58-A270-68EFE089BB09}',
'192.168.8.14',
'192.168.8.1')
>>>

对于Route类,还有增加、删除路由,以及改变网卡接口地址等功能

 

二、、功能:

1、读写报文:

 rdpcap函数、wrpcap函数

使用wrpcap()函数可以把构造报文写到文件中,

>>> pkt=Ether()/IP(dst='192.168.8.1')/TCP(dport=80)
>>> pkt.summary()
'Ether / IP / TCP 192.168.8.14:ftp_data > 192.168.8.1:http S'
>>> wrpcap(r'f:\pkt.pcap',pkt)
>>>

 

使用rdpcap()函数可以把文件中的报文读到列表中,然后对每个报文可以按协议分层访问各层字段:

>>> newpkt=rdpcap(r'f:\pkt.pcap')
>>> newpkt
<pkt.pcap: TCP:1 UDP:0 ICMP:0 Other:0>

>>> newpkt[0][IP]
<IP version=4 ihl=5 tos=0x0 len=40 id=1 flags= frag=0 ttl=64 proto=tcp chksum=0xe96f src=192.168.8.14 dst=192.168.8.1 |<TCP sport=ftp_data dport=http seq=0 ack=0 dataofs=5 reserved=0 flags=S window=8192 chksum=0xfe1e urgptr=0 |>>
>>> newpkt[0][IP].src

'192.168.8.14'
>>> newpkt[0][IP].dst
'192.168.8.1'

 

2、抓包:

(1) 抓包用sniff函数,函数定义:sniff(filter:str,count:int,iface:str,prn:func)更多更纤细的参数看help(sniff).

其中参数prn为回调函数,每抓到一个符合过滤器规则的包就以其为参数传入执行一次prn函数,通常用lambda写prn;

参数filter,和wireshark的capture filter规则一样。

>>> ping=sniff(filter="icmp",iface='WLAN',count=5,prn=lambda pkt:pkt.summary())
Ether / IP / ICMP 192.168.8.14 > 192.168.8.1 echo-request 0 / Raw
Ether / IP / ICMP 192.168.8.1 > 192.168.8.14 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.8.14 > 192.168.8.1 echo-request 0 / Raw
Ether / IP / ICMP 192.168.8.1 > 192.168.8.14 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.8.14 > 192.168.8.1 echo-request 0 / Raw
>>>
>>> ping[0].summary()
'Ether / IP / ICMP 192.168.8.14 > 192.168.8.1 echo-request 0 / Raw'
>>> ping[4].summary()
'Ether / IP / ICMP 192.168.8.14 > 192.168.8.1 echo-request 0 / Raw'
>>>

 

(2)也可以离线抓包,就是从文件中读取报文,功能和rdpcap相同,不过对匹配的报文可以过滤,调用回调函数,控制更灵活:

sniff(offline = "hw.pcap");

 

(3)sprintf()方法可以控制输出信息,该方法是scapy自己定义的替换控制符,替换变量用%括起来,如下:

sniff(prn=lambda pkt:pkt.sprintf("{IP:%IP.src% -> %IP.dst%\n}{Raw:%Raw.load%\n}"))

 

3、构造报文:

(1)报文根据协议层次构造,使用”/”堆加层次,注意字母大小写,如:

>>> ipPacket = IP()/TCP()
>>> ipPacket
<IP frag=0 proto=tcp |<TCP |>>
>>> ipPacket.summary()
'IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:http S'
>>>

每个层次具有的协议字段可以通过ls命令查看如:

 

 

 

构造报文时可以根据自己的需要设置协议的某些字段,如:

 ipPacket = IP(dst='8.8.8.8')/TCP(dport=53)

 

上面是构造单个报文,可以利用元组和列表方式一次构造一系列报文,

如果用元组,则表示范围(包含边界值),如下:

>>> ipPackets = IP(dst='192.168.8.1')/TCP(sport=(10000,10005), dport=80)
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10001 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10002 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10003 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10004 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10005 dport=http |>>]
>>>

>>> send(ipPackets)
......
Sent 6 packets.
>>>

>>> ipPackets = IP(dst='192.168.8.1')/TCP(sport=range(10000,10005), dport=80)
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10001 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10002 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10003 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10004 dport=http |>>]
>>>

如果用列表,则表示用列表中的每个元素构建,如下:

>>> ipPackets = IP(dst='192.168.8.1')/TCP(sport=[10000,10005], dport=80)
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10005 dport=http |>>]
>>>

>>> send(ipPackets)
..
Sent 2 packets.
>>>

 

也可以混合使用,如:

>>> ipPackets = IP(dst='192.168.8.1')/TCP(sport=[10000,(2000,2002),10005], dport=80)
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=2000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=2001 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=2002 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10005 dport=http |>>]
>>>

 

对于ip地址访问,可以使用列表方式指定,也可以指定掩码方式构造一系列不同报文,这对于构造扫描报文很有用,如:

>>> ipPackets = IP(dst=['192.168.8.1','192.168.8.2'])/TCP(sport=10000, dport=80)
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.2 |<TCP sport=10000 dport=http |>>]
>>>

>>> ipPackets = IP(dst='192.168.8.1/30')/TCP(sport=10000, dport=80)
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=192.168.8.0 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.1 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.2 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=192.168.8.3 |<TCP sport=10000 dport=http |>>]
>>>

 

ip地址也可以使用域名,scapy会自动通过Net函数进行地址解析:

>>> ipPackets = IP(dst='www.sina.com.cn/30')/TCP(sport=10000, dport=80)

>>> ipPackets
<IP frag=0 proto=tcp dst=Net("www.sina.com.cn/30") |<TCP sport=10000 dport=http |>>
>>> list(ipPackets)
[<IP frag=0 proto=tcp dst=175.153.178.216 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=175.153.178.217 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=175.153.178.218 |<TCP sport=10000 dport=http |>>,
<IP frag=0 proto=tcp dst=175.153.178.219 |<TCP sport=10000 dport=http |>>]
>>>

 

堆叠数据层,构建系列数据包:

>>> a=IP(ttl=[1,2,3])
>>> b=TCP(dport=(20,21))
>>> ab=a/b
>>> list(ab)
[<IP frag=0 ttl=1 proto=tcp |<TCP dport=ftp_data |>>,
<IP frag=0 ttl=1 proto=tcp |<TCP dport=ftp |>>,
<IP frag=0 ttl=2 proto=tcp |<TCP dport=ftp_data |>>,
<IP frag=0 ttl=2 proto=tcp |<TCP dport=ftp |>>,
<IP frag=0 ttl=3 proto=tcp |<TCP dport=ftp_data |>>,
<IP frag=0 ttl=3 proto=tcp |<TCP dport=ftp |>>]
>>>

 

(2)报文的查看:

针对报文,可以查看概要信息,分层字段信息,16进制偏移格式等,

summary(),show(),hexdump()

 

 

 

>>> hexdump(ipPacket)
0000 45 00 00 28 00 01 00 00 40 06 E9 6F C0 A8 08 0E E..([email protected]....
0010 C0 A8 08 01 27 10 00 50 00 00 00 00 00 00 00 00 ....'..P........
0020 50 02 20 00 D7 22 00 00 P. .."..
>>>

 

(3)查看报文有指定的协议层使用haslayer函数,获取指定层使用getlayer函数,如下:

>>> ipPacket.haslayer(TCP)
True
>>> tcp=ipPacket.getlayer(TCP)
>>> tcp
<TCP sport=10000 dport=http |>
>>> tcp.sport
10000
>>>

 

4、发送和接收报文:

sendp,send,srp,sr,srp1,sr1,srloop等函数

数字1表示只发送1个报文,带有字母p表示发送构造了二层帧的报文,没有字母p的函数表示发送三层报文,有字母r表示发送报文后还会接收报文。

没有数字1表示可以发送1个或多个报文(报文列表)

>>> pkt=IP(dst='192.168.8.1')/TCP(sport=RandNum(30000,30010),dport=80,flags='S')

>>> send(pkt)
.
Sent 1 packets.
>>>
>>> send([pkt,pkt])
..
Sent 2 packets.


>>> send(pkt *10)
..........
Sent 10 packets.
>>>

 

 

发送tcp/udp报文:

>>>sr1( IP(dst='192.168.8.1')/TCP(sport=50000,dst=80,flags='S'))

报文构造中,很多地方都要用到随机数,scapy也定义了相应随机函数,如RandInt(),RandShort(), RandNum()和Fuzz()等用来生成随机数。

RandInt(),顾名思义,产生一个32位随机整数,通常用在tcp的seq或ack中:

>>> int(RandInt())
3023505333

 

RandShort(),产生一个16位随机整数,范围1~65535,通常用在tcp/udp的sport或dport中。

>>> int(RandShort())

53905

 

 

 

RandNum(),可以生成指定范围内的一个随机数

>>> int(RandNum(3000,4000))
3709

pkt=IP(dst='192.168.8.1')/TCP(sport=RandNum(30000,30010),dport=80,flags='S')

 

 

 

fuzz(),通常情况下,如果你构建tcp层没有指定sport或dport时,发包时会自动使用知名端口如20,80。这可能并不是你想要的。

而fuzz()函数能够在忘记写sport或dport情况下,自动帮你随机生成sport或dport

如下:

 

 

 

循环发送报文: 

srloop(pkts, *args, **kargs)
Send a packet at layer 3 in loop and print the answer each time
srloop(pkts, [prn], [inter], [count], ...) --> None

srloop(IP(dst="192.168.8.1")/TCP(),count=2,inter=0.5)

 

发送dns查询报文,注意里面的RR等构造需要借助DNSQR等方法:

>>> p = sr1(IP(dst="8.8.8.8") / UDP() / DNS(qdcount=1,qd=DNSQR(qclass=1, qtype=1, qname='www.maipu.com')))
Begin emission:
Finished sending 1 packets.
...*
Received 4 packets, got 1 answers, remaining 0 packets
>>>

>>> qr=DNSQR(qclass=1, qtype=1, qname='www.baidu.com')
>>> qr
<DNSQR qname='www.maipu.com' qtype=A qclass=IN |>
>>> qr.show()
###[ DNS Question Record ]###
qname = 'www.baidu.com'
qtype = A
qclass = IN

>>>





 

标签:8.1,IP,报文,scapy,基础,192.168,TCP,模块,dst
From: https://www.cnblogs.com/dingbj/p/scapy.html

相关文章

  • Java学习笔记(十三) 前端基础2
    Ajax介绍概念:AsynchronousJavaScriptAndXML,异步的JavaScript和XML作用:数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想,用户名是否可用的校验等......
  • 衡量模块独立的定性标准是什么?
    衡量模块独立的定性标准可以从以下几个方面考虑:高内聚:模块内部的各个组件或功能之间的耦合度尽可能低,每个模块只负责一个特定的功能或者一组相关的功能,模块内部的代码都是围绕这个特定功能或者功能组织的。模块内部的代码实现应该尽可能简单,避免过于复杂的逻辑或者算法。低......
  • Java学习笔记(十二) 前端基础1
    Web前端基础初识web前端网页由哪些部分组成?文字图片音频视频超链接等我们看到的网页,背后的本质是什么?程序员写的前端代码前端的代码是如何转换成用户眼中的网页的?通过浏览器转化(解析和渲染)成用户看到的网页浏览器中对代码进行解析渲染的部分,称为浏......
  • 什么是模块化?为什么要模块化
    什么是模块化为什么要模块化模块化是指将一个大的系统或程序分解成独立的模块,每个模块都有自己的功能和接口。在编写代码时,开发人员可以将代码分成多个模块,每个模块只负责特定的任务或功能。这样做的好处是可以提高代码的可重用性、可维护性和可扩展性。下面是一些模块化的好......
  • 文件系统基础
    磁盘使用步骤  1.先把磁盘分区    每个分区可以使用不同的文件系统格式  2.把分区格式化    为每个分区创建inode表    一般占用磁盘的1%    inode介绍                        管道和重......
  • Java基础语法
    用户交互Scanner实验importjava.util.Scanner;publicclassDome01{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);System.out.println("使用Next方式接受");if(scanner.hasNext()){......
  • PHP5.6常用模块安装
    1、常用命令查看编译参数:php-I查看加载模块:php-m查看模块详情:php--ri模块名2、redis扩展tarxfredis-4.2.0.tgz\&&cdredis-4.2.0\&&/opt/php/bin/phpize\&&./configure--with-php-config=/opt/php/bin/php-config\&&make-j2\&&ma......
  • 光纤光缆的基础知识
      光 纤  光纤,完整名称叫做光导纤维,英文名是OPTICFIBER。它是一种由玻璃或塑料制成的纤维,可作为光传导工具。光纤的主要用途,是通信。目前通信用的光纤,基本上是石英系光纤,其主要成分是高纯度石英玻璃,即二氧化硅(SiO2)。光纤通信系统,就是利用光纤来传......
  • 物联网技术基础及应用绪论
    物联网技术基础及应用绪论  任课教师:北京化工大学毕超课程链接:https://www.bilibili.com/video/BV1ha411g7H2/?spm_id_from=333.999.0.0&vd_source=e66dd25b0246f28e772d75f11c80f03c课程版本:2022版涉及语言:Android、Html/CSS/JavaScript、PHP、C涉及工具:MySQL(Linux)、N......
  • 【THM】Windows Fundamentals 2(Windows基础知识2)-学习
    本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/windowsfundamentals2x0x本文介绍:本文所涉及的内容是Windows基础模块的第2部分,了解有关系统配置、UAC设置、资源监控、Windows注册表等更多信息。简介在WindowsFundamentals1中,我们已经介绍了Windows的桌面......