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

使用Scapy发送PCAP数据包时,如何使应用层数据与原始文件一致?

问题描述

我使用Scapy读取PCAP数据包并修改头部后发送至服务器,代码如下:

print(f"sending pcap packets to {self.dst_ip}:{self.dst_port}")
packs = scp.rdpcap(self.pcap)

new_src_mac = get_mac_address(ip="0.0.0.0")
new_dst_mac = self.dstmac

for pkt in packs:
    pkt[scp.Ether].src = new_src_mac
    pkt[scp.Ether].dst = new_dst_mac
    pkt[scp.IP].src= self.src_ip 
    pkt[scp.IP].dst= self.dst_ip
    pkt[scp.TCP].sport = self.src_port
    pkt[scp.TCP].dport = self.dst_port
    pkt[scp.TCP].ack = ack_num
    pkt[scp.TCP].seq = seq_num
    scp.sendp(pkt, iface=self.iface)

发送后通过Wireshark抓包发现,发送的数据包应用层数据显示为十六进制格式,但原始PCAP文件中的数据包并非如此。请问如何发送出与原始文件格式一致的数据包?

解决方法

问题根源在于Scapy修改TCP/IP头部后,会自动重构数据包结构,导致应用层载荷被处理为原始字节(Wireshark默认显示为十六进制),而非原始PCAP中被识别为特定协议的格式。可以通过以下步骤解决:

  • 禁用自动校验和计算,保留原始载荷
    Scapy默认会重新计算IP和TCP的校验和,可能干扰数据包结构。修改代码时手动处理校验和,同时固定应用层载荷:
print(f"sending pcap packets to {self.dst_ip}:{self.dst_port}")
packs = scp.rdpcap(self.pcap)

new_src_mac = get_mac_address(ip="0.0.0.0")
new_dst_mac = self.dstmac

for pkt in packs:
    # 保存原始TCP应用层载荷
    original_payload = pkt[scp.TCP].payload
    
    # 修改链路层头部
    pkt[scp.Ether].src = new_src_mac
    pkt[scp.Ether].dst = new_dst_mac
    
    # 修改IP头部,删除原有校验和让Scapy重新计算
    pkt[scp.IP].src = self.src_ip
    pkt[scp.IP].dst = self.dst_ip
    del pkt[scp.IP].chksum
    
    # 修改TCP头部,删除原有校验和,设置序列号和确认号
    pkt[scp.TCP].sport = self.src_port
    pkt[scp.TCP].dport = self.dst_port
    pkt[scp.TCP].ack = ack_num
    pkt[scp.TCP].seq = seq_num
    del pkt[scp.TCP].chksum
    
    # 恢复原始应用层载荷
    pkt[scp.TCP].payload = original_payload
    
    # 发送数据包
    scp.sendp(pkt, iface=self.iface)
  • 强制用Raw层包裹原始载荷
    如果Scapy仍自动解析载荷,可将原始载荷转为Raw类型,避免被重新解析:
for pkt in packs:
    # 提取原始载荷的字节数据
    raw_payload = bytes(pkt[scp.TCP].payload)
    
    # 执行所有头部修改操作...
    
    # 用Raw层包裹原始载荷
    pkt[scp.TCP].payload = scp.Raw(load=raw_payload)
    
    scp.sendp(pkt, iface=self.iface)
  • 检查Wireshark解码设置
    有时并非数据包本身问题,而是Wireshark未正确识别应用层协议。可在Wireshark中右键点击目标数据包,选择「解码为」,手动指定对应应用层协议,验证显示是否恢复正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:50:35