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

使用Scapy通过Socket实现IPsec AH隧道模式的报文重构问题

问题:Scapy重构IPsec AH隧道模式报文失败

环境配置

  • AH隧道模式
  • 外层IP源地址:192.168.100.4
  • AH头部Next Header字段设为IPv4
  • 内层报文:10.0.1.2到10.0.1.1的ICMP请求报文

发送端代码及生成的报文结构

from scapy.all import SecurityAssociation, AH, IP, ICMP, raw

# 安全关联(Security Association)配置
sa = SecurityAssociation(AH, spi=0x222, auth_algo='SHA2-384-192', auth_key=b'secret key', tunnel_header=IP(src='192.168.100.4', dst='192.168.100.6'))

# 构造并加密报文
packet = packet_from_Interface  # 内层IP+ICMP报文
e1 = sa.encrypt(packet)
print("AH packet:")
e1.show()

生成的报文结构:

###[ IP ]### 
  version   = 4
  ihl       = 5
  tos       = 0x0
  len       = 140
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = ah
  chksum    = 0x30e3
  src       = 192.168.100.4
  dst       = 192.168.100.6
  \options   \
###[ AH ]### 
     nh        = 4
     payloadlen= 7
     reserved  = None
     spi       = 0x222
     seq       = 2
     icv       = 266cd31bc38315f1091b8c9affb181b9ec8b33a43b9cb50d
     padding   = None
###[ IP ]### 
        version   = 4
        ihl       = 5
        tos       = 0x0
        len       = 84
        id        = 7564
        flags     = DF
        frag      = 0
        ttl       = 64
        proto     = icmp
        chksum    = 0x71b
        src       = 10.0.1.2
        dst       = 10.0.1.1
        \options   \
###[ ICMP ]### 
           type      = echo-request
           code      = 0
           chksum    = 0xc8bb
           id        = 0x7
           seq       = 0x1
           unused    = ''
###[ Raw ]### 
              load      = '\x0e\\x8fLf\x00\x00\x00\x00\x12t\x03\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'

接收端代码及实际结果

接收端代码:

recv_packet = IP(byte_packet_received)
recv_packet.show()

实际输出的报文结构:

###[ IP ]### 
  version   = 4
  ihl       = 5
  tos       = 0x0
  len       = 128
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = ah
  chksum    = 0x30ef
  src       = 192.168.100.4
  dst       = 192.168.100.6
  \options   \
###[ AH ]### 
     nh        = 4
     payloadlen= 4
     reserved  = 0
     spi       = 0x222
     seq       = 1
     icv       = ebf23a021ee0bbf47fab24ac
     padding   = 
###[ Raw ]### 
        load      = 'E\x00\x00T\\xabS@\x00@\x01yS\n\x00\x01\x02\n\x00\x01\x01\x08\x00\\xabB\x00\x08\x00\x01ߒLf\x00\x00\x00\x00X\\xe8\t\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'

问题分析与解决建议

核心问题

  1. Scapy默认不会自动根据AH头部的Next Header字段解析后续协议层,导致内层IP报文被识别为Raw负载。
  2. 接收端解密时SA配置可能与发送端不一致,或报文序列(seq)不匹配,导致验证失败。

解决步骤

1. 手动解析内层IP报文

接收端需提取AH层的负载,根据nh字段(值为4对应IPv4)重新解析为IP报文:

from scapy.all import IP, AH

recv_packet = IP(byte_packet_received)
# 提取AH层
ah_layer = recv_packet[AH]
# 解析内层IP
inner_ip_pkt = IP(ah_layer.payload)
inner_ip_pkt.show()  # 此时可正常识别内层IP和ICMP细节

2. 确保SA配置完全一致

解密必须使用与发送端完全相同的安全关联参数,包括SPI、认证算法、密钥:

from scapy.all import SecurityAssociation

# 与发送端完全一致的SA配置
sa = SecurityAssociation(AH, spi=0x222, auth_algo='SHA2-384-192', auth_key=b'secret key', tunnel_header=IP(src='192.168.100.4', dst='192.168.100.6'))

try:
    decrypted_pkt = sa.decrypt(recv_packet)
    print("解密成功:")
    decrypted_pkt.show()
except Exception as e:
    print(f"解密失败原因:{e}")

3. 排查报文序列(seq)问题

发送端报文seq为2,接收端显示为1,需确认:

  • 发送时SA的seq是否正确递增(Scapy的SA会自动递增seq,但需确保每次加密使用同一个SA实例)
  • 接收的报文是否为发送端发出的目标报文(可能存在报文丢失或顺序错乱)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:24:53