我们将了解 Scapy 的工作原理以及我们如何使用它来创建我们自己的网络操作工具。 让我们创建一个名为 1.py 的新文件并打开它。 打开文件后,我们可以导入文件中的任何 Scapy 模块。 在本节中,我们将为任何网站创建一个小的 ping 请求。 Ping 请求通常用于测试设备是否可用。 ping 请求(也称为回显请求)
#-*- coding:utf-8 -*-
from scapy.all import ICMP #使用底层 ICMP 应用层协议。 要在程序中导入包
from scapy.all import IP #要发送 ping 请求,您需要创建一个 IP 层数据包,这将帮助您设置源和目标 IP 地址。 要导入 IP 层。
from scapy.all import sr1 #最后,为了发送和接收数据包,我们可以使用一个名为 sr 的函数。 要导入此函数
#然后,我们将定义我们的源 IP 和目标 IP:
src_ip = "10.201.3.112"
dest_ip = "www.baidu.com"
#现在,我们将创建一个 ip_layer 数据包并将其打印出来以查看其中包含的内容
ip_layer = IP(
src = src_ip,
dst = dest_ip
)
print(ip_layer.show())
该程序的输出如下所示:
python .\1.py
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = ip
chksum = None
src = 10.201.3.112
dst = Net("www.baidu.com/32")
\options \
None
查看 src 和 dst 字段。 目标是 Net 的一个实例,这意味着 Scapy 将负责将其转换为实际的 IP 地址。
接下来,要发送 ICMP 请求,您可以调用该类来创建这样的实例:
icmp_req = ICMP(id=100)
id=100 帮助协议跟踪数据包。 要查看此请求中存在哪些字段,您可以编写以下命令:
print(icmp_req.show())
###[ ICMP ]###
type = echo-request
code = 0
chksum = None
id = 0x64
seq = 0x0
unused = ''
None
从这里可以看出,数据包类型是回显请求,用于测试连接可用性。
我们知道应用层位于 IP 层之上,到目前为止我们已经创建了两个层。 现在,下一个目标是将这两层组合成一个可以通过网络发送的数据包。 为此,我们可以编写以下代码:
packet = ip_layer / icmp_req
print(packet.show())
这将列出组合的数据包。 注意 / 运算符。 该运算符用于在 Scapy 中组合不同的层。 您从较低的层开始,并使用此 / 运算符继续添加新层。 打印结果将显示与前几层合并为一个的数据包的结果:
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = icmp
chksum = None
src = 10.201.3.112
dst = Net("www.baidu.com/32")
\options \
###[ ICMP ]###
type = echo-request
code = 0
chksum = None
id = 0x64
seq = 0x0
unused = ''
None
现在,我们的请求已准备好发送。 要发送它,我们可以使用我们已经导入的 sr1 方法:
response = sr1(packet, iface="WLAN")
if response:
print(response.show())
Begin emission:
Finished sending 1 packets.
.......................................................*
Received 56 packets, got 1 answers, remaining 0 packets
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 28
id = 1
flags =
frag = 0
ttl = 47
proto = icmp
chksum = 0x7a5d
src = 220.181.38.149
dst = 10.201.3.112
\options \
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0xff9b
id = 0x64
seq = 0x0
unused = ''
None
可以看到响应的类型是echo-reply,响应中的src字段是响应这个ping请求的服务器的IP地址。
现在您已经学习了如何使用 Python 制作和发送数据包。 理论上,您可以使用 Scapy 创建任何网络应用程序。
前面提到的发送数据包的完整代码如下所示:
#-*- coding:utf-8 -*-
from scapy.all import ICMP
from scapy.all import IP
from scapy.all import sr1
src_ip = "10.201.3.112"
dest_ip = "www.baidu.com"
ip_layer = IP(
src = src_ip,
dst = dest_ip
)
#print(ip_layer.show())
icmp_req = ICMP(id=100)
#print(icmp_req.show())
packet = ip_layer / icmp_req
#print(packet.show())
#response = sr1(packet, iface="以太网")
response = sr1(packet, iface="WLAN")
if response:
print(response.show())
Scapy 的好处是它允许您创建 raw_packets,这意味着即使包含错误信息的数据包(格式错误的数据包)也可以创建,并且没有检查数据包是否具有正确值的机制。 您可以更改计算机的 src ip 字段并放入其他数据包的值,在某些情况下,目的地将无法知道实际生成这些数据包的 PC(空闲扫描)。 这样,您就可以欺骗数据包。
所以,到目前为止,我们已经了解了 IP 堆栈和标头字段。 我们还学习了如何安装 Scapy 并使用它来创建可以通过网络发送的原始数据包。 现在让我们来看看一些更有帮助的函数,它们将帮助我们更详细地了解 Scapy 的工作原理。
如果您想查看 Scapy 中某个图层的更多详细信息以及该图层中有哪些选项可以修改,可以使用 Scapy 中的 ls 函数。 要导入此函数,您可以使用以下命令:
>>> from scapy.all import ls, IP
>>> dest_ip = "www.baidu.com"
>>> ip_layer = IP(dst = dest_ip)
>>> print(ls(ip_layer))
version : BitField (4 bits) = 4 ('4')
ihl : BitField (4 bits) = None ('None')
tos : XByteField = 0 ('0')
len : ShortField = None ('None')
id : ShortField = 1 ('1')
flags : FlagsField = <Flag 0 ()> ('<Flag 0 ()>')
frag : BitField (13 bits) = 0 ('0')
ttl : ByteField = 64 ('64')
proto : ByteEnumField = 0 ('0')
chksum : XShortField = None ('None')
src : SourceIPField = '10.201.3.112' ('None')
dst : DestIPField = Net("www.baidu.com/32") ('None')
options : PacketListField = [] ('[]')
None
要获取有关 ip_layer 的信息,我们可以像这样打印 ls:
如果要访问任何图层的单个字段,只需使用点 (.) 运算符即可。 比如要在ip_layer中打印dst,可以编写如下代码:
>>> ip_layer = IP(dst = dest_ip)
>>> print("Destination = ", ip_layer.dst)
Destination = 180.101.49.11
如果想查看图层的快速汇总,可以调用图层上的汇总方法:
>>> print("Summary = ",ip_layer.summary())
Summary = 10.201.3.112 > Net("www.baidu.com/32") ip
所以现在,我们已经熟悉了 Scapy 及其工作原理。 我们学习了创建基本数据包以及如何操作这些数据包。 在下一节中,我们将介绍如何使用 Scapy 进行信息收集。