在 Scapy 中发送原始数据不能正常工作

Sending raw data in Scapy does not work correctly

我使用 Scapy 创建一个初始 OpenVPN 数据包并将其发送到 OpenVPN 服务器(作为客户端)。数据包的 OpenVPN 部分我只是从旧的捕获连接中重用,但它在这里无关紧要。

事实是,我添加了 42 字节的有效负载,但出于某种原因,当我使用 Wireshark 捕获数据包时,我可以看到 84 字节的 OpenVPN 内容。后半部分是我发送的正确负载,但我不知道前半部分是什么。所有其他层(以太网、IP、UDP)的大小都正确。

#!/usr/bin/env python
import socket
from scapy.all import *

mysocket=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
mysocket.connect(('192.168.138.129', 1194))

mystream=StreamSocket(mysocket)

ascapypacket=Ether()/IP(dst="192.168.138.129")/UDP(dport=1194, len=50)/Raw(load="\x38\x81\x38\x14\x62\x1d\x67\x46\x2d\xde\x86\x73\x4d\x2c\xbf\xf1\x51\xb2\xb1\x23\x1b\x61\xe4\x23\x08\xa2\x72\x81\x8e\x00\x00\x00\x01\x50\xff\x26\x2c\x00\x00\x00\x00\x00")

etherLoad = len(ascapypacket.getlayer(Ether)) # display size
print etherLoad
ipLoad = len(ascapypacket.getlayer(IP)) # display size
print ipLoad
udpLoad = len(ascapypacket.getlayer(UDP)) # display size
print udpLoad
rawLoad = len(ascapypacket.getlayer(Raw)) # display size
print rawLoad

mystream.send(ascapypacket)

我做了一个图像。在这里你可以看到绿色的东西是正确的 - 第一部分是 IP 和 UDP 层,第二个绿色部分是我的 OpenVPN 有效负载,但我不明白红色部分是什么。

编辑:如果我不发送原始负载,出于某种原因我仍然会收到这 42 个字节。

您已经创建了一个普通的 UDP 数据报套接字:

mysocket=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

此套接字自行管理 ethernetIPUDP 层,有指导来自用户的各种辅助方法和参数,例如您在代码片段中实际使用的 connect 方法:

mysocket.connect(('192.168.138.129', 1194))

它的各种 send 方法,即使封装为 scapyStreamSocket object 的一部分,也期望收到他们的 "data-to-send" 参数只是位于 UDP 层之上的应用程序负载。
但是,您将整个协议栈有效负载传递给它,即 ethernetIP & UDP headers,它被误解为您希望发送到另一端的有效负载数据的一部分:

ascapypacket=Ether()/IP(dst="192.168.138.129")/UDP(dport=1194, len=50)/Raw(load="\x38\x81\x38\x14\x62\x1d\x67\x46\x2d\xde\x86\x73\x4d\x2c\xbf\xf1\x51\xb2\xb1\x23\x1b\x61\xe4\x23\x08\xa2\x72\x81\x8e\x00\x00\x00\x01\x50\xff\x26\x2c\x00\x00\x00\x00\x00")

因此,您用红色标记的数据实际上是您自己设置的负载数据,然后是OpenVPN部分:

Ether()/IP(dst="192.168.138.129")/UDP(dport=1194, len=50)

绿色标记的第一部分,你误认为是自己创建的,实际上是由socket object(内核,相应的driver和底层硬件,更准确地说)。


根据您的需要,您应该将套接字实例化为原始套接字:

mysocket = socket(socket.AF_PACKET, socket.SOCK_RAW)

或相应地设置负载为 OpenVPN 数据:

ascapypacket=Raw(load="\x38\x81\x38\x14\x62\x1d\x67\x46\x2d\xde\x86\x73\x4d\x2c\xbf\xf1\x51\xb2\xb1\x23\x1b\x61\xe4\x23\x08\xa2\x72\x81\x8e\x00\x00\x00\x01\x50\xff\x26\x2c\x00\x00\x00\x00\x00")