Scapy的基本操作
Kubrnete 227 4

Scapy的基本操作

1.IP()类型数据包

在Scapy中,每一个协议就是一个类。只需要实例化一个协议类,就可以创建一个该协议的数据包。例如,如果要创建一个IP类型的数据包,就可以使用如下命令。

ip = IP()
ip.show()

运行结果: 在这里插入图片描述

IP数据包最重要的属性就是源地址和目的地址,这两个属性可以使用src和dst来设置。

例如,要构造一个发送“192.168.43.1”的IP数据包,可以使用下面代码:

ip = IP(dst="192.168.43.1")
ip.show()

运行结果: 在这里插入图片描述

这个目标的dst的值可以是一个IP地址,也可以是一个IP范围,例如192.168.43.0/24,这时产生的就不是1个数据包了。而是256个其中包括了192.168.43.0 最后以 192.168.43.255 结束。

ip_range = "192.168.43.0/24"
ip = IP(dst=ip_range)
for i in ip:
    i.show()

部分运行结果: 在这里插入图片描述 2.Ether协议 Scapy采用分层的形式来构造数据包,通常最下面的一个协议为Ether,然后是IP,再之后是TCP或者UDP。

IP()函数无法用来构造ARP请求和应答数据包,所以这时可以使用Ether(),这个函数可以设置发送方和接收的MAC地址。

那么现在来产生一个广播数据包,执行的命令如下:

data = Ether(dst="ff:ff:ff:ff:ff:ff")
data.show()

运行结果如下: 在这里插入图片描述

当我们想要构造一个TCP数据包时。 我们可以用Ether()/IP()/TCP()来完成一个TCP数据包。

data = Ether()/IP()/TCP()
data.show()

在这里插入图片描述

想要查看Ether()类和IP()类的属性可以使用ls(Ether())和ls(IP())进行查看

在这里插入图片描述

Scapy模块中的函数

Scapy中提供了多个用来完成发送数据包的函数,首先来看一下其中的send()和sendp()。

这两个函数的区别在于send()工作在第三层,而sendp()工作在第二层。

简单来说,send()是用来发送IP数据包的,而sendp()是用来发送Ether数据包的。

例如,构造一个目的地址为“192.168.43.1”的ICMP数据包,并将其发送出去,可以使用下面的代码进行发送。

data = IP(dst="192.168.43.1") / ICMP()
send(data)

当我们发送成功时就会显示“Sent 1 packets”等字样。 在这里插入图片描述 当我们使用Ether()时就需要使用sendp()进行发送了。

data = Ether(dst="5a:0e:ec:04:59:d3")
send(data)

这个里的目的地址我填写的是MAC地址。

同样也会回显“Sent 1 packets”等字样 在这里插入图片描述

值得注意的是,这两个函数的特点是只发不收,也就是说只会将数据包发送出去,但是没有能力处理该数据包的回应包。

在网络的各种应用中,需要做的不仅是将创建好的数据包发送出去,也需要接收这些数据包的应答数据包,这一点在网络扫描中尤为重要。

在Scapy中提供了三个用来发送和接收数据包的函数,分别是sr(),sr1(),srp(),其中,sr()和sr1()主要用于第三层,例如IP和ARP等,而srp()用于第二层。

这里仍然向192.168.43.1发送一个ICMP数据包来比较一下sr()和send()的区别。

1. sr()

data = IP(dst="192.168.43.1") / ICMP()
sr(data)

运行结果: 在这里插入图片描述

data = IP(dst="192.168.43.1") / ICMP()
print(sr(data))

运行结果: 在这里插入图片描述 我们用print进行输出时会发现有两个元素,所以我们需要使用两个变量进行存储。

data = IP(dst="192.168.43.1") / ICMP()
ans, unans = sr(data)
ans.summary()

使用summary()进行查看数据包里的内容

在这里插入图片描述

2. sr1()

data = IP(dst="192.168.43.1") / ICMP()
sr1(data)

运行结果: 在这里插入图片描述

这里我们可以发现使用sr()和sr1()回显的结果都是相同的,同样都是有4个应答。

使用summary()进行查看数据包里的内容

data = IP(dst="192.168.43.1") / ICMP()
print((sr1(data).summary()))

在这里插入图片描述 例如,我们想要探测某个主机的端口是否开放,采用半开扫描(SYN)的办法

data = IP(dst="192.168.43.1") / TCP(dport=80,flags="S")
ans, unans = sr(data)
ans.summary()

运行结果: 在这里插入图片描述 我们运行之后可能对下列的输出结果有些不太明白,其实这里的整体意思是本地20端口向目标80端口发起一个SYN,当目标收到时就会回应一个SYN+ACK给我们本地,这里很明显它是收到了,并且还回复了,证明目标端口是打开的,关闭的不会有任何回应。

IP / TCP 192.168.43.156:ftp_data > 192.168.43.1:https S ==> IP / TCP 192.168.43.1:https > 192.168.43.156:ftp_data RA

利用Scapy进行端口屏蔽探测

在此之前我们先看看这几个图 在这里插入图片描述 在这里插入图片描述

使用Scapy来实现一次ACK类型的端口扫描,例如对192.168.43.1的21、23、135、443、445这5个端口是否被屏蔽进行扫描,注意是屏蔽而不是关闭,采用ACK扫描模式,可以构造如下的代码:

from scapy.all import *

port = [21, 23, 135, 443, 445]
data = IP(dst="192.168.43.1") / TCP(dport=port, flags="A")
ans, unans = sr(data)
ans.summary()
for s, r in ans:
    print("发送:" + s.summary())
    print("回复:" + r.summary())
for s, r in ans:
    if s[TCP].dport == r[TCP].sport:
        print("未过滤端口:" + str(s[TCP].dport))

运行结果: 在这里插入图片描述

预览图
评论区

索引目录