飞道的博客

【Python】scapy模块学习笔记

234人阅读  评论(0)

0x00 scapy安装以及环境配置

学习自知乎大佬 ——弈心——网络工程师的Python之路—Scapy基础篇
复现了一波

scapy安装:

pip install scapy

导入scapy方式:

from scapy.all import *

然后是环境配置

kali的IP地址为192.168.43.245,使用的网卡为eth0

物理机的IP地址为192.168.43.1,就是kali的网关

进入scapy,这里我是在kali2020里面进行发送scapy构造的数据包,然后在本机用wireshark进行抓包接收。

物理机监听kali使用的这块网卡

然后是scapy的一些基本用法

首先是ls()命令,用来查看scapy支持的网络协议

除了ls()外,还可以用lsc()函数来查看scapy的指令集(函数)

这里还可以用使用ls()的携带参数模式,比如ls(IP)来查看IP包的各种默认参数。

0x01 实验1

实验目的:使用IP()函数构造一个目的地址为192.168.2.11(即拓扑中的交换机S1)的IP报文,然后用send()函数将该IP报文发送给S1,在S1上开启debug ip packet以验证是否收到该报文。

首先用IP()函数构造一个目的地址为192.168.43.1的IP报文,将其实例化给ip这个变量

ls(ip)查看这个报文的内容

然后用send()将这个数据包发送给物理机,send()函数只发送不接受

可以看到物理机已经接收到了这个ip报文

0x02 实验2

实验目的:除了send()外,scapy还有个sendp()函数,两者的区别是前者是发送三层报文,后者则是发送二层报文,实验2将演示如何用sendp()来构造二层报文。

除了send()外,scapy还有个sendp()函数,两者的区别是前者是发送三层报文,后者则是发送二层报文,实验2将演示如何用sendp()来构造二层报文。

先构造一个arp报文,如下

arp = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(hwsrc="00:0c:29:ef:29:24",psrc="192.168.43.245",pdst="192.168.43.1")/'abc'


这里我们构造了一个源MAC地址为00:0c:29:ef:29:24, 源IP地址为192.168.43.245,,目标IP地址为192.168.43.1,payload为abc的ARP报文。

然后sendp()发送出去

sendp(arp)


可以看到物理机接收到了来自kali的arp数据包,询问192.168.43.1的mac地址,并且物理机也把自己的mac地址返回给了kali

0x03 实验3

实验目的:从实验1和实验2的例子可以看出:send()和sendp()函数只能发送报文,而不能接收返回的报文。如果要想查看返回的3层报文,需要用到sr()函数,实验3将演示如何使用sr()函数。

先构造一个目的地址为物理机的ICMP()包。可以看到返回的结果是一个tuple(元组),该元组里的元素是两个列表,其中一个列表叫Results(响应),另一个叫Unanswered(未响应)。

我们可以将sr()函数返回的元组里的两个元素分别赋值给两个变量,第一个变量叫ans,对应Results(响应)这个元素,第二个变量叫unans,对应Unanswered(未响应)这个元素。

wireshark捕获到了发送给物理机的icmp包和物理机的应答包

0x04 实验4

实验目的:实验3讲到了sr(),它是用来接收返回的3层报文。实验4将使用srp()来接收返回的2层报文。

用srp()配合Ether()和ARP()构造一个arp报文,二层目的地址为ff:ff:ff:ff:ff:ff,三层目的地址为192.168.2.0/24, 因为我们是向整个/24网络发送arp, 耗时会很长,所以这里用timeout = 5,表示将整个过程限制在5秒钟之内完成

ans, unans = srp(Ether(dst = "ff:ff:ff:ff:ff:ff") / ARP(pdst = "192.168.43.0/24"), timeout = 5)

wireshark捕获到了从192.168.43.1到192.168.43.254的整个c段的arp包,因为只有192.168.43.1(物理机)、192.168.43.2(dns服务器)和192.168.43.245(kali),所以只会收到三个应答包

下面用ans.summary()来具体看看到底是哪3个IP响应了我们的’who has’类型的arp报文。

ans.summary()


用unans.summary()来查看那些没有给予我们’who has’类型arp报文回复的IP地址
可以看到询问其他IP的’who has’类型arp报文没有人响应。我们可以用这个方法来写一个python判断存活主机的脚本,向局域网整个段发送arp、icmp请求,如果收到回应即为存活,否则为不存活。可以参考这篇博客:使用python的scapy和nmap模块进行主机存活探测

0x04 实验5

实验目的:使用tcp()函数构造四层报文,理解和应用RandShort(),RandNum()和Fuzz()函数。

用nmap来扫描一下物理机开启了哪些端口,这里就用8082端口来测试

在scapy上使用ip()和tcp()函数来构造一个目的地IP为192.168.43.1(物理机),源端口为30,目的端口为8082的TCP SYN报文。

ans, unans = sr(IP(dst = "192.168.43.1") / TCP(sport = 30, dport = 8082, flags = "S"))

wireshark捕获到了三次tcp握手

TCP端口号除了手动指定外,还可以使用RandShort(), RandNum()和Fuzz()这几个函数来让scapy帮你自动生成一个随机的端口号,通常可以用作sport(源端口号)。

首先来看RandShort(),RandShort()会在1-65535的范围内随机生成一个TCP端口号,将上面的sport = 30 替换成 sport = RandShort()即可使用。

ans, unans = sr(IP(dst = "192.168.43.1") / TCP(sport = RandShort(), dport = 8082, flags = "S")/"test")

这里可以看到RandShort()替我们随机生成了53780这个TCP源端口号


如果你想指定scapy生成端口号的范围,可以使用RandNum(),比如你只想在1000-1500这个范围内生成端口号,可以使用RandNum(1000,1500)来指定,举例如下:

ans, unans = sr(IP(dst = "192.168.43.1") / TCP(sport = RandNum(666,888), dport = 8082, flags = "S")/"test")

这里RandNum()帮我们生成了837这个源端口号


转载:https://blog.csdn.net/qq_44657899/article/details/115838385
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场