Python渗透测试——一、数据包的编辑工具——Scapy

news2024/10/5 23:50:19

Python渗透测试

  • 一、Scapy简介
  • 二、Scapy中的分层结构
  • 三、Scapy中的常用函数
  • 四、在Scapy 中发送和接收数据包
  • 五、Scapy 中的抓包函数

一、Scapy简介

提到数据包(这里泛指帧、段和报文等)的构造,我们首先需要了解协议和分层这两个概念。在“互联世界的规则一协议”中,我们提到了协议的概念,简单来说协议就是通信时所有参与者必须遵守的规则集合。这些协议各司其职、各尽其能,它们的不同主要体现在产生的数据包的顺序与格式上。

个在网络中的数据包往往会包含多个协议,例如我们所使用的 QQ,它在登录时就会产生数据包。这个数据包的目标地址是腾讯服务器(假设为 1.1.1.1),目标端口是 8000,传输的信息为“我要登录”,那么这个过程产生的数据包就需要包含 IP 部分(用来指明目标地址等信息)UDP 部分(用来指明端口等信息 、QQ 自有协议部分(用来保存传输内容等)。实际情况远比这要复杂,互联网上存在的协议数量已经成千上万了,当多个协议存在于同一个数据包时,为了解析方便,就有必要将它们分成不同的层次。
目前通用的分层方式有两种,我们以相对简单的 TCP/IP 协议族为例,它是一个4层协议模型、自底而上分别是链路层、网络层、传输层和应用层。每一层完成不同的功能,且通过若干协议来实现,上层协议使用下层协议提供的服务。
在这里插入图片描述
TCP/IP 协议族常见协议所属层次
这样分层之后来构造数据包就会很简单。但是需要注意,一个数据包并不是必须同时包含这 4层的协议,也不是同一层只能包含1个协议。在后面的具体实现中,我们就会对此有深入的了解。
在这里插入图片描述
前面提到 Scapy 是一个可以直接操作到数据包层次的工具。在 Windows 中,我们可以在Python 环境中将Scapy 当作一个库使用;如果是在 Linux中则可以将 Scapy 当作一个独立的工具来使用,它提供了一个和Python相同的交互式命令行环境。在Kali Linux2.0中已经集成了 Scapy 环境,只需要启动一个终端,输入命令“scapy”,就可以启动 Scapy编程环境。
Scapy 提供了和 Python 一样的交互式命令行。这里需要特别强调的是,虽然将 Scapy 模块作为 Python 的一个库,但是 Scapy 本身就是一个可以独立运行的工具,它具备一个独立的运行环境,因而可以不依赖Python。

二、Scapy中的分层结构

首先我们先用几个实例来演示 Scapy 的用法。Scapy 使用了“类+属性”的方法来构造数据包,在 Scapy 中每一个网络协议就是一个类,协议中的字段就对应着属性。只需要实例化一个协议类,就可以创建一个该协议类型的数据包。例如我们要构造一个 IP 数据包,可以使用如下方式。

IP()

如果要使用 IP 的话,那么首先需要导人 Scapy 库。考虑到目标模块中的属性非常多,反复输人 Scapy 很不方便,这里我们选择“from 模块 import 类”的形式导人,下面给出了一个使用Scapy构造IP 数据包的演示程序

from scapy.all import IP
pkt=IP()
print(pkt)

在这里插入图片描述

这个程序执行之后,可以输出中看到的结果:
在这里插入图片描述
对于 IP 来说,最重要的属性就是源地址和目标地址,这两个属性在 Scapy中使用参数 src和 dst来设置。例如我们要构造一个发往“192.168.217.150”的IP 数据包,就可以使用以下语句。

ip=IP(dst="192.168.217.150")

对于 Scapy 的使用者来说,比较困难的一点就是协议类型众多。现在使用IPO来构造数据包的时候,都需要设置哪些参数,这些参数都有什么意义呢?由于网络中协议数量众多,因此Scapy 在内部实现了大量的网络协议 (DNS、ARP、IP、TCP、UDP 等)。人类靠记忆来完成这个工作是很难的。
要想熟练地使用 Scapy,大家需要掌握协议的一些基础知识。另外 Scapy 也提供了一个可以便捷查看数据包格式的函数ls(),当你不了解如何为一个 IP 数据指定目标地址的时候、就可以使用下面的程序。

from scapy.all import IP,ls
pkt=IP()
ls (pkt)

执行该程序,可以看到结果。
在这里插入图片描述
在这里插入图片描述
Scapy 采用分层的方式来构造数据包,通常最底层的协议为 Ether,然后是 IP,再之后是TCP 或者 UDP。例如我们使用 Ether0,这个类可以设置发送方和接收方的 MAC 地址。那么我们现在来产生一个广播数据包,执行的命令如下。

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

分层是通过符号“/”实现的。如果一个数据包是由多层协议组合而成的,那么这些协议之间就可以使用“/”分开,并按照协议由底而上的顺序从左向右排列。例如我们可以使用Ether()/IP()/TCP()来构造一个TCP数据包。

from scapy.all import
pkt=Ether()/IP()/TCP()
ls(pkt)

在这里插入图片描述
在这里插入图片描述
这个程序由于需要导入的模块比较多,因此使用了“import *”。在执行这个程序之后,可以看到我们构造了一个包含 Ether、IP 和TCP 这3 种协议的数据包。
如果要构造一个HTTP 数据包,也可以使用以下这种方法。
在这里插入图片描述

三、Scapy中的常用函数

Scapy中使用频率最高的类要数 Ether IPTCP和UDP了,这些类都具有哪些属性呢?Eth类中显然具有源地址、目标地址和类型。IP类的属性则复杂了许多,除了最重要的源地址和目地址之外,还有版本、长度、协议类型、校验和等。TCP 类中具有源端口和目标端口。这里我可以使用ls()函数来查看一个类所拥有的属性。前面我们已经提过了,这个函数使用属性列表的式来显示一个数据包的详细信息,例如使用ls(Ether0)来查看 Ether 类的属性。
在这里插入图片描述
也可以使用同样的方法用ls(IP())来查看 IP 类的属性,可以对属性列表里对应的属性进行设置,例如我们将 ttl 的值设置为 32,就可以使用如下方式。

pkt=IP(src="192.168.1.1",dst="192.168.1.101",ttl=32)

在这里插入图片描述
刚开始不熟悉 Scapy 有哪些功能的时候,大家可以使用 lsc()函数列出所有可以使用的函数,下面给出了一些经常使用的函数及其使用方法。首先我们使用 pkt=IP()来构造一个数据包然后利用这个 pkt 来演示各种函数。

  • raw()函数表示以字节格式来显示数据包内容。例如我们如果要查看 pkt,就可以使用 print(raw(pkt))。
  • hexdump()函数表示以十六进制数据表示的数据包内容给出了print(hexdump(pkt))的执行结果。
  • summary()函数使用不超过一行的摘要内容来简单描述数据包,pkt.summary()让使用者可以简单明了地知晓数据包的内容。
  • show()函数使用展开视图的方式显示数据包的详细信息,是一种比较常用的方法,使用者可以快速看到每一个属性的值,给出了 pkt,show()的执行结果。
  • show2()函数的作用与 show()的基本相同,区别在于使用 pkt.show2()时会显示数据包的校验和。

如果我们看到了一个数据包,但是不知道如何使用命令来产生相同的数据包时,就可以使用command()函数,它可以显示出构造该数据包的命令。例的就是用 pkt.command()还原 pkt 的构造命令。

有时使用 Scapy 会捕获到大量的数据包,这些数据包需要保存起来,例如在网络取证时就会经常这么做,这时 wrpcap()函数就可以完成这个工作。例如我们在程序中将很多数据包都临时存储在 pkts 中,使用wrpcap("temp.cap",pkts)就可以将pkts 中的数据包写入文件 temp.cap。

同样 Scapy 也提供了读取数据包文件的功能,rdpcap()函数就可以实现这个功能,例如使用pkts =rdpcap("temp.cap")读取 temp.cap文件中的数据包。

四、在Scapy 中发送和接收数据包

除了这些对应着协议的类和它们的属性之外,我们还需要一些可以实现各种功能的函数需要注意的一点是,刚才我们使用 IP()的作用是产生了一个 IP 数据包,但是并没有将其发送出去,因此现在首先需要将产生的数据包发送出去。Scapy 提供了多个用来发送数据包的函数先来看其中的 send()函数和 sendp()函数。这两个函数的区别在于 send()数是用来发送IP数据包的,而sendp()函数是用来发送 Ether 数据包的。我们先来构造一个目标地址为 192.168.1.1的ICMP 数据包,并将其发送出去,可以使用如下程序。

from scapy.all import *
pkt=IP(dst="192.168.217.150")/ICMP()
send(pkt)

在这里插入图片描述
在这里插入图片描述
注意,如果这个数据包发送成功,那么下方会有一个“Sent 1 packets”的显示。sendp()函数的使用方法是相同的,下面给出了一个实例。

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

简单来说,当你需要将 MAC 地址作为目标时,就使用 sendp()函数;而当你需要将IP 地址作为目标时,就使用 send()函数。这两个函数的特点是只发不收,也就是说只会将数据包发送出去,但是不会处理该数据包的应答数据包。

在网络的各种应用中,我们需要做的不仅要将创建好的数据包发送出去,也要接收这些数据包的应答数据包,这一点在网络扫描中尤为重要。Scapy 提供了 3 个用来发送和接收数据包的丽数,分别是 sr()函数、sr1()函数和 srp()函数,其中 sr()函数和 sr1()函数主要用于 IP 地址,而srp()丽数用于MAC地址。

这里我们仍然向192.168.217.150发送一个ICMP 数据来了解 sr()函数的使用方法需要注意的是,这里 192.168.217.150 应该是一个可以 ping通的地址。

当产生的数据包被发送出去之后,Scapy 就会监听接收到的数据包,将其中对应的应答数据包筛选出来并显示。为 Reveived 表示收到的数据包个数,answers 表示对应此次发送数据包的应答数据包。

sr()函数是 Scapy 的核心,它的返回值是两个列表,第一个列表包含收到了应答的数据包和对应的应答数据包,第二个列表包含未收到应答的数据包。所以可以使用两个列表来保存sr()函数的返回值。

from scapy.all import *
pkt=IP(dst="192.168.217.150")/ICMP()
ans,uans=sr(pkt)
ans.summary()

在这里插入图片描述
在这里插入图片描述
这里我们使用ans列表和 uans列表来保存sr()函数的返回值。因为发送出去的是一个ICMP数据包,而且收到了一个应答数据包,所以这个发送的数据包和收到的应答数据包都被保存到了ans列表中使用ans.summary0可以查看两个数据包的内容。unans列表为空。为ans中保存的应答数据包。

srl()雨数跟 sr()丽数作用基本一样,但是只返回一个应答数据包,只需要使用一个列表可以保存这个雨数的返回值。srp()丽数与 srl()函数和 sr()函数的区别在于发送时要使用 MAC地址。

五、Scapy 中的抓包函数

另外,一个十分重要的函数是 snim0。如果你使用过 Tcpdump,那么对这个函数就不会感到陌生。使用这个函数就可以在自己的程序中捕获经过本机网卡的数据包了。

sniff()

这个函数完整的格式为sniff(filter="",iface="any”,prn=function,count=N)。第1个参数是filter,可以用来对数据包进行过滤。例如我们指定只捕获与 192.168.217.150有关的数据包,就可以使用host 192.168.217.150"

sniff(filter="host 192.168.1.1")

但是这种仅依靠IP地址来过滤的方法有很大的局限性,下面我们介绍一种功能更加完善的方法。1993年史蒂文·麦卡内(Steven McCanne)与范·雅各布森( Van Jacobson)在USENIX93会议上提出了一种机制一伯克利包过滤(Berkeley Packet Filter,BPF)它采用了一种与自然语言很接近的语法,利用这种语法构成的字符串可以确定保留哪些数据包以及忽略哪些数据包。

这种语法很容易理解。例如最简单的空字符串,表示的就是匹配所有数据包,也就是保留所有的数据包。如果这个字符串不为空,那么只有那些使字符串表达式值为“真”的数据包才会被保留。这种字符串通常由一个或者多个原语所组成,每个原语又由一个标识符(名称或者数字)组成,后面跟着一个或者多个限定符。

伯克利包过滤中的限定符有下面3种:

  • Type:这种限定符表示指代的对象,例如 IP 地址子网或者端口等。常见的有 host(用来表示主机名和 IP 地址)、net(用来表示子网)、port(用来表示端口)。如果没有指定,默认为 host。
  • Dir:这种限定符表示数据包传输的方向,常见的有 src(源地址)和 dst(目的地)如果没有指定,则默认为“src or dst”。例如 192.168.217.151表示的就是匹配源地址或者目标地址为 192.168.217.150的数据包。
  • Proto:这种限定符表示与数据包匹配的协议类型,常见的就是 Ether、IP、TCP、ARP这些协议。

伯克利包过滤中的标识符指的就是那些进行测试的实际内容,例如一个 IP 地址 192.168.217.151,一个子网192.168.217.0/24 或者一个端口号 8080,这些都是常见的标识符。host 192.168.217.151和 port 8080 是两个比较常见的原语,我们还可以用 and、or 和 not 把多个原语组成一个更复杂的过滤语句。例如host 192.168.217.151 and port 8080 就是一个符合规则的过滤语句。
下面给出了一些常见的原语实例。

  • host 192.168.1.1:当数据包的目标地址或者源地址为 192.168.1.1 时,过滤语句为真。
  • dst host 192.168.1.1:当数据包的目标地址为 192.168.1.1时,过滤语句为真
  • src host 192.168.1.1:当数据包的源地址为 192.168.1.1 时,过滤语句为真。
  • ether host 11:22:33:44:55:66:当数据包的以太网源地址或者目标地址为 11:22:33:44:55:66时,过滤语句为真。
  • ether dst 11:22:33:44:55:66:当数据包的以太网目标地址为 11:22:33:44:55:66 时,过语句为真。
  • ether src 11:22:33:44:55:66:当数据的以太网源地址为11:22:33:44:55:66 时过滤语句为真
  • dst net 192.168.1.0/24:当数据包的IP4/IPv6 的目标地址的网络号为192.168.1.0/24时过滤语句为真。
  • src net 192.168.1.0/24:当数据包的IPV4/IPv6 的源地址的网络号为19216810/24时过滤语句为真。
  • net 192.168.1.0/24:当数据包的IPV4/IPV6 的源地址或目标地址的网络号为192.168.1.0/24时,过滤语句为真。
  • dst port 8080:当数据是TCP 或者UDP 数据包且目标端口号为8080时过滤语为真。
  • src port 8080:当数据包是TCP 或者UDP 数据包且源端口号为 8080 时,过滤语句为真。
  • port 8080:当数据包的源端口或者目标端口为 8080 时,过滤语句为真。所有的 port前面都可以加上关键字TCP或者UDP。

第2个参数 iface 用来指定要使用的网卡,默认为第一块网卡。
第3个参数 prn表示对捕获到的数据包进行处理的函数,可以使用 Lambda 表达式。例如我们要将获取到的数据包输出,就可以使用以下函数。

sniff(filter="icmp", prn=lambda x:x.summary())

如果这个函数比较长,也可以定义成回调函数。这个回调函数以接收到的数据包对象作为唯一的参数,最后再调用 sniff()函数。

def packet_callback(pkt):
	print (pkt,summary)
sniff(prn=packet.callback)

第4个参数 count 用来指定监听到数据包的数量,达到指定的数量就会停止监听。例如我们只希望监听到 10 个数据包就停止。

sniff(count=10)

我们来设计一个综合性的监听器,它会在网卡 eth0 上监听源地址或者目标地址为 192.168.1.1 的1CMP 数据包并输出,当收到了3个这样的数据包之后,就会停止监听。建的监听器如下:

sniff(filter="icmp and host 192,168,1,1",prn=lambda x:x,summary(),count=3)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1297177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

概率论之 证明 正态分布的上a 分位点的对称的性质

公式(Z(a) -Z(1-a)) 表示正态分布的上(a)分位点与下(1-a)分位点在分布曲线上关于均值的对称性。 左侧 (Z(a)): 这是分布曲线上累积概率为(a)的那个点。也就是说,这是一个使得这个点及其左侧的面积占据整个曲线下方(a)的位置。 右侧 (Z(1-a))&#xff1…

网页设计--第6次课后作业

试用Vue相关指令完成对以下json数据的显示。显示效果如下: 其中:gender1 显示为女,gender2显示为男。价格超过30元,显示“有点小贵”。价格少于等于30元,则显示“价格亲民”。 data: {books: [{"id": "…

Selenium IED安装及简单使用

本文已收录于专栏 《自动化测试》 目录 背景介绍优势特点安装步骤录制脚本总结提升 背景介绍 Selenium 通过使用 WebDriver 支持市场上所有主流浏览器的自动化。 Webdriver 是一个 API 和协议,它定义了一个语言中立的接口,用于控制 web 浏览器的行为。 每…

基于Unity3D 低多边形地形模型纹理贴图

在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时,有几种不同的风格&#xf…

springboot + thymeleaf + layui 初尝试

一、背景 公司运营的同事有个任务,提供一个数据文件给我,然后从数据库中找出对应的加密串再导出来给他。这个活不算是很难,但时不时就会有需求。 同事给我的文件有时是给excel表格,每一行有4列,逗号隔开,…

RocketMQ-RocketMQ高性能核心原理(流程图)

1.NamesrvStartup 2.BrokerStartup 3. DefualtMQProducer 4.DefaultMQPushConsumer

LeetCode-数组-重叠、合并、覆盖问题-中等难度

435. 无重叠区间 我认为区间类的题型,大多数考验的是思维能力,以及编码能力,该类题型本身并无什么算法可言,主要是思维逻辑,比如本题实际上你只需要能够总结出重叠与不重叠的含义,再加上一点编码技巧&#…

【上海大学数字逻辑实验报告】五、记忆元件测试

一、实验目的 掌握R-S触发器、D触发器和JK触发器的工作原理及其相互转换。学会用74LS00芯片构成钟控RS触发器。学会用74LS112实现D触发器学会在Quartus II上用D触发器实现JK触发器。 二、实验原理 基本R-S触发器是直接复位-置位的触发器,它是构成各种功能的触发器…

解读Stable Video Diffusion:详细解读视频生成任务中的数据清理技术

Diffusion Models视频生成-博客汇总 前言:Stable Video Diffusion已经开源一周多了,技术报告《Stable Video Diffusion: Scaling Latent Video Diffusion Models to Large Datasets》对数据清洗的部分描述非常详细,虽然没有开源源代码,但是博主正在尝试复现其中的操作。这篇…

基于ssm平面设计课程在线学习平台系统源码和论文

idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 随着信息化时代的到来,管理系统都趋向于智能化、系统化,平面设计课程在线学习平台系统也不例外,但目前国内的市场仍都使用人工管理,市场规模越来越大,…

chrome安装jsonview

写在前面 通过jsonview可以实现,当http响应时application/json时直接在浏览器格式化显示,增加可读性。本文看下如何安装该插件到chrome中。 1:安装 首先在这里 下载插件包,然后解压备用。接着在chrome按照如下步骤操作&#xf…

JAVEE初阶 多线程基础(七)

懒汉模式 指令重排序问题 一. 懒汉模式的意义和代码实现二. 饿汉模式和懒汉模式的线程安全三. 懒汉模式的线程安全问题解决3.1 加锁阶段3.2 嵌套if阶段3.3 指令重排序问题3.4 解决线程安全问题阶段 一. 懒汉模式的意义和代码实现 在上一章节中,我们先学习了单例模式中的饿汉模式…

go语言学习-并发编程(并发并行、线程协程、通道channel)

1、 概念 1.1 并发和并行 并发:具有处理多个任务的能力 (是一个处理器在处理任务),cpu处理不同的任务会有时间错位,比如有A B 两个任务,某一时间段内在处理A任务,这时A任务需要停止运行一段时间,那么会切换到处理B任…

基于redisson实现发布订阅(多服务间用避坑)

前言 今天要分享的是基于Redisson实现信息发布与订阅(以前分享过直接基于redis的实现),如果你是在多服务间基于redisson做信息传递,并且有服务压根就收不到信息,那你一定要看完。 今天其实重点是避坑&#xff0…

MySQL 对null 值的特殊处理

需求 需要将不再有效范围内的所有数据都删除,所以用not in (有效list)去实现,但是发现库里,这一列为null的值并没有删除,突然想到是不是跟 anull 不能生效一样,not in 对null不生效,也需要特殊处理。 解决 …

$sformat在仿真中打印文本名的使用

在仿真中,定义队列,使用任务进行函数传递,并传递文件名,传递队列,进行打印 $sformat(filename, “./data_log/%0d_%0d_%0d_0.txt”, f_num, lane_num,dt); 使用此函数可以自定义字符串,在仿真的时候进行文件…

Python基础(二、必备知识,不用背,用用就会了~)

一、基础知识 1.标识符 在Python中,标识符是用来标识变量、函数、类、模块或其他对象的名称。一个有效的标识符由字母、数字和下划线组成,且不能以数字开头。Python是区分大小写的,因此myVariable和myvariable被视为不同的标识符。 下面是…

Redis数据已经删除了,为什么内存占用还是很高?

Redis数据已经删除了,为什么内存占用还是很高? Redis做了数据删除操作,为什么使用top命令时,还是显示Redis占了很多内存? 没做相关功课的人觉得这个问题有问题,删了数据还说占着内存,面试官不…

QQ2023备份

需要修改的路径(共3处) 这三处路径中,只有一处是需要修改的 QQPC端-主菜单-设置-基本设置-文件管理 点击上面的“”自定义“”,然后修改路径即可 修改路径后提示 然后等一会才会关干净QQ的相关进程,关闭后才会有自动…

Windows的C盘爆掉了怎么办?

本文参考: C盘太满怎么办?亲测8种好用方法! 如果C盘的分区爆掉了,变红色了,是时候该处理这个问题了,解决你的C盘焦虑! 第一招:删除C盘文件 首先你会想到清理C盘里面的文件&#x…