Scapy 是一个功能强大的 Python 库,用于构建、发送和解析网络数据包。它可以用于各种网络应用,例如网络安全、网络分析或网络测试。
以下是关于 Scapy 的教学,包括安装、基本原理和示例:
安装 Scapy
你可以使用以下命令在 Python 环境中安装 Scapy:
pip install scapy
Scapy 基本原理
Scapy 可以用于构建、发送和解析网络数据包。它支持众多网络协议和数据包类型,包括 IP、TCP、UDP、ICMP、ARP 等。你可以使用 Scapy 创建自定义数据包,并以特定协议的格式发送它。你还可以捕获网络接口的流量、分析和篡改数据包。
Scapy 主要包含以下功能:
- 构建网络数据包:通过 Scapy,你可以使用各种协议的名称和参数构建自定义数据包,然后将其发送到网络中。
- 发送数据包:Scapy 允许你直接以 Python 代码的方式指定数据包并发送它。
- 解析数据包:Scapy 可以解析已捕获的网络数据包,以可读、易于操作的 Python 对象的形式呈现它们。
- 嗅探数据包:使用 Scapy,你可以在网络中捕获数据包,并进一步分析和操作它们。
Scapy 二层探测教程
Scapy 简介
Scapy 是一个灵活的和强大的 Python 库,可用于构建和发送网络数据包,同时也可以用于嗅探和分析网络流量。使用 Scapy,你可以以编程方式生成和操作各种网络协议,并且很容易地扩展和定制它来满足你的特定需求。
实现 ARP 探测
下面我们将演示如何使用 Scapy 实现 ARP 探测,这是一个很有用的工具来查找网络中其他设备的存在,以及获取它们的 MAC 地址和 IP 地址。
from scapy.all import *
# 构建 ARP 请求数据包
packet = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst="192.168.0.1")
# 发送数据包并等待响应
result = srp(packet, timeout=1, verbose=False)
# 处理响应数据包
if result:
for sent, received in result:
print("收到响应:")
print(received.summary())
首先,我们构建了一个发送到广播地址的 ARP 请求数据包,并设置其中目标 IP 地址为 “192.168.0.1”。然后,我们使用 srp()
函数发送数据包并等待响应,verbose=False
参数表示不输出详细的调试信息。
如果我们有响应,我们可以遍历 result
返回的元组列表并打印出每个响应数据包的 summary()
,以获取设备的 MAC 和 IP 地址。
实现 LLDP 探测
下面我们将演示如何使用 Scapy 实现 LLDP 探测,这是一个用于发现和获取网络设备信息的协议。
from scapy.all import *
# 构建 LLDP 帧
packet = Ether(dst="01:80:c2:00:00:0e")/LLDP(
TLVList=[
LLDPChassisID(subtype=4, length=7, chassis_id="1234567"),
LLDPChassisID(subtype=5, length=4, chassis_id="eth0"),
LLDPManagementAddress(subtype=1, length=12, address="192.168.0.1"),
LLDPManagementAddress(subtype=2, length=6, address="00:11:22:33:44:55")
]
)
# 发送数据包并等待响应
result = srp(packet, timeout=1, verbose=False)
# 处理响应数据包
if result:
for sent, received in result:
print("收到响应:")
print(received.summary())
首先,我们构建了一个 LLDP 帧,并添加了一些 LLDP TLV(Type-Length-Value)来指定发送者的一些信息,如物理接口、管理 IP 地址等。
接下来,我们使用 srp()
函数发送数据包并等待响应。如果我们有响应,我们可以遍历 result
返回的元组列表并打印出每个响应数据包的 summary()
,以获取目标设备的信息。
嗅探二层流量
下面我们将演示如何使用 Scapy 嗅探网卡上的二层流量,以获取发送和接收的网络数据包。
from scapy.all import *
# 定义嗅探回调函数
def packet_callback(packet):
if packet.haslayer(Ether):
print("捕获到二层数据包")
print(packet.summary())
# 启动嗅探器
sniff(prn=packet_callback, filter="ether")
首先,我们定义了一个嗅探回调函数 packet_callback()
,该函数处理每个捕获到的网络数据包。如果我们捕获到二层数据包(即具有 Ether 层),我们打印出数据包的摘要信息。然后,我们使用 sniff()
函数启动嗅探器。prn
参数指定了嗅探回调函数,即每个捕获到的数据包都会传递给该函数进行处理。filter
参数可以用于过滤嗅探的数据包,例如我们在这里使用了 “ether” 过滤器,表示只捕获二层数据包。
您可以运行以上代码,在嗅探器运行期间发送一些网络数据包,它们将被捕获并输出其摘要信息。
Scapy 三层信息搜集教程
Scapy 简介
Scapy 是一个灵活的和强大的 Python 库,可用于构建和发送网络数据包,同时也可以用于嗅探和分析网络流量。使用 Scapy,你可以以编程方式生成和操作各种网络协议,并且很容易地扩展和定制它来满足你的特定需求。
实现获取IP信息的示例
下面我们将演示如何使用 Scapy 获取网络中的 IP 地址和关联的 MAC 地址信息。
from scapy.all import *
# 获取本机网络接口
interfaces = get_if_list()
print(f"本机网络接口:{interfaces}")
# 获取接口 IP 地址
for iface in interfaces:
if "eth" in iface or "en" in iface:
try:
iface_ip = get_if_addr(iface)
print(f"{iface} 的 IP 地址为:{iface_ip}")
iface_mac = get_if_hwaddr(iface)
print(f"{iface} 的 MAC 地址为:{iface_mac}")
except:
print(f"{iface} 未启用或未分配 IP 地址")
首先,我们使用 get_if_list()
函数获取本机的网络接口列表,并打印出来。
然后,我们遍历所有以 “eth” 或 “en” 开头的网络接口,使用 get_if_addr()
函数获取它们的 IP 地址,并使用 get_if_hwaddr()
函数获取它们的 MAC 地址。
您可以运行以上代码,获取本机的 IP 地址和 MAC 地址信息。
实现获取主机信息的示例
下面我们将演示如何使用 Scapy 获取网络中主机的信息,例如主机名、操作系统类型和开放的端口列表等。
from scapy.all import *
# 获取本机 IP 地址
local_ip = socket.gethostbyname(socket.gethostname())
print(f"本机 IP 地址:{local_ip}")
# 发起 ARP 请求,获取局域网中的其他主机信息
conf.verb = 0
arp = ARP(pdst="192.168.1.0/24")
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether / arp
result = srp(packet, timeout=3)[0]
hosts = []
for sent, received in result:
hosts.append({"ip": received.psrc, "mac": received.hwsrc})
print("\n局域网中的主机信息:")
print("-" * 40)
print("IP\t\t\tMAC")
print("-" * 40)
for host in hosts:
print(f"{host['ip']}\t\t{host['mac']}")
# 获取目标主机的操作系统类型
os_detect = OSFingerPrint()
results = os_detect.process_hosts(hosts=[host["ip"] for host in hosts], max_threads=5, user=os.geteuid())
for host, result in results:
print(f"{host}\n{'*' * 40}\n{result}")
# 获取目标主机开放的端口列表
target_ip = input("请输入目标主机 IP 地址:")
port_scan = TCP().sport()
responded, unanswered = sr(IP(dst=target_ip)/port_scan, retry=5, timeout=5)
print(f"目标主机 {target_ip} 开放的端口列表:")
for packet in responded:
print(packet[IP].src, packet[TCP].sport)
scapy四层信息搜集
首先,我们使用 socket
模块获取本机的 IP 地址,并打印出来。
然后,我们使用 ARP 协议发起广播请求,获取局域网中的其他主机信息。通过在 hosts
列表中保存每个主机的 IP 地址和 MAC 地址,我们可以实现在局域网中搜集主机信息。
接下来,我们获取每个主机的操作系统类型,并使用 OSFingerPrint
类的 process_hosts()
方法实现。您需要足够的权限才能执行此操作。
通过 Scapy,我们可以方便地进行网络嗅探、ICMP ping、TCP/UDP 端口扫描等操作,同时可以自定义协议进行数据包的创建与解析。下面我会提供一个四层信息搜集的示例,来介绍 Scapy 的使用。
示例: 获取 TCP、UDP、ICMP 和 DNS 信息
from scapy.all import *
# 定义一个回调函数
def packet_callback(packet):
print("------------------------------")
print(f"Source: {packet[IP].src} -> Destination: {packet[IP].dst}")
print(f"Protocol: {packet[IP].proto}")
if packet.haslayer(TCP):
print("TCP Port: " + str(packet[TCP].dport))
elif packet.haslayer(UDP):
print("UDP Port: " + str(packet[UDP].dport))
elif packet.haslayer(ICMP):
print(f"ICMP Type: {packet[ICMP].type} Code: {packet[ICMP].code}")
elif packet.haslayer(DNS):
print(f"DNS Query: {packet[DNS].qd.qname.decode()}")
# 开始嗅探网络流量
sniff(prn=packet_callback, filter="ip", store=0)
在以上代码中,我们使用了 Scapy 的 sniff()
函数来嗅探网络流量,通过 filter
参数只保留 IP 数据包,并将每个数据包都传入 packet_callback()
函数中进行处理。在回调函数中,我们首先输出源 IP 和目的 IP 信息,然后判断数据包的协议类型,如果是 TCP、UDP、ICMP 或 DNS 中的一种,就分别输出相关信息。
您可以复制以上代码并执行,打开一些网址,并观察输出结果。由于我们在代码中过滤了只保留 IP 数据包,因此只会输出 IP 数据包的信息。