gpt4 book ai didi

python - 虚拟数据包字段 : how to handle a polymorphic protocole?

转载 作者:太空宇宙 更新时间:2023-11-03 12:04:34 25 4
gpt4 key购买 nike

我是一个新的 scapy 用户,今天我请求你的帮助。

我正在尝试在 scapy 中添加一个新的协议(protocol)。这个protocol有点特别,因为他极度多态。通过多态,我的意思是他的结构和长度取决于某些领域。通常,有一个“功能”ByteField,更改此值会更改所有后续字段。

那么,让我们看看这段代码,说明我想做什么。有一个简单的多态数据包,其主要常量结构为//header//parameter//data//。变体在参数和数据结构中。

### VIRTUAL PARAMETER PACKET
class myPacketParam(Packet):
name = "Virtual Param Packet"

### REAL PARAMETER PACKET ONE
class myPacketParamOne(myPacketParam):
name = "Parameter Type One"
fields_desc = [
ByteField("paramOne", 0x0),
ByteField("paramTwo", 0x0)
]

### REAL PARAMETER PACKET TWO
class myPacketParamTwo(myPacketParam):
name = "Parameter Type Two"
fields_desc = [
FieldLenField("length", None, length_of="stringOpt"),
StrLenField("stringOpt", "BAGUETTE", # Random default value
length_from=lambda pkt: pkt.length)
]

### VIRTUAL DATA PACKET
class myPacketData(Packet):
name = "Virtual Data Packet"

### REAL DATA PACKET ONE
class myPacketDataOne(myPacketData):
name = "Data Type One"
fields_desc = [
ByteField("length", 2),
ByteField("dataOne", 0x0),
ByteField("dataTwo", 0x0)
]

### REAL DATA PACKET TWO
class myPacketDataTwo(myPacketData):
name = "Data Type Two"
fields_desc = [
FieldLenField("length", None, length_of="data"),
StrLenField("data", "SAUCISSON", length_from=lambda pkt: pkt.length) # Random default value
]

### MAIN PACKET
class myPacket(Packet):
name = "myPacket"

def changeFunction(self, value, data):
if value == 0x1:
self.param = myPacketParamOne()
self.data = myPacketDataOne()
else:
self.param = myPacketParamTwo()
self.data = myPacketDataTwo()

fields_desc = [
ByteField("version", 0x15),
ActionField(ByteField("function", 0x1), "changeFunction"),
FieldLenField("lengthParam", None, length_of="param"),
FieldLenField("lengthData", None, length_of="data"),
PacketField("param", myPacketParamOne(), myPacketParam),
PacketField("data", myPacketDataOne(), myPacketData)
]

好吧,重点是主数据包“myPacket”中的“param”和“data”字段。例如,“param”packetfield 请求一个 myPacketParam 数据包。但我希望这个数据包是虚拟的:后面的真实数据包可以是 myPacketParamOne 或 myPacketParamTwo。数据也是如此。

构建这个数据包看起来没问题。

p = myPacket()
p.show()

# great result

p.function = 2
p.show()

###[ myPacket ]###
version = 21
function = 2
lengthParam= None
lengthData= None
\param \
|###[ Parameter Type Two ]###
| length = None
| stringOpt = 'BAGUETTE'
\data \
|###[ Data Type Two ]###
| length = None
| data = 'SAUCISSON'

但我猜解剖工作不正常。

p.show2()

###[ myPacket ]###
version = 21
function = 2
lengthParam= 10
lengthData= 11
\param \
|###[ Virtual Param Packet ]###
|###[ Raw ]###
| load = 'BAGUETTE\x00\tSAUCISSON'
\data \
|###[ Data Type One ]###
| length = 2
| dataOne = 0
| dataTwo = 0

这是完全错误的。

我找到了一些解决方案。通过使用 conditionalField 的示例。但是在我的真实协议(protocol)中,同一个数据包中有很多形态。并且因为字段不能有相同的名称,所以在主数据包中没有一个简单的参数字段,而是每个案例的新名称。因此,真正利用我的 scapy 实现非常无聊且不简单。

第二种解决方案是取消链接 header 、参数和数据。所以你可以像这样使用协议(protocol):p = myPacket()/myPacketParamOne()/myPacketDataOne()。但这对我来说不是一个好的解决方案,因为我真正的协议(protocol)在每个部分之间都有依赖关系,而且对于我的 scapy 实现的用户来说仍然很复杂。

因此,如果可能的话,我正在寻找解决方案:- 尊重主要结构(标题/参数/数据)- 简单使用此协议(protocol)(myPacket.param.whatyouwant 获取参数而不考虑它是什么类型的参数包(但当然 whatyouwant 字段存在于这种参数包中))

我觉得解决方案可以是在每个“虚拟数据包”中重新定义 do_dissect 函数,或者专门为虚拟数据包编写一个新字段,但我尝试了很多东西都没有成功。

我希望我是可以理解的。

提前谢谢你:)

内森

最佳答案

(这个有点老了^^)

自最近版本的 Scapy(使用 2.4.3rc+ 以确保安全)以来,我们有一个新的 MultipleTypeField 似乎可以满足您的需求。这是回归测试中的示例:

class DebugPacket(Packet):
fields_desc = [
ByteEnumField("atyp", 0x1, {0x1: "IPv4", 0x3: "DNS", 0x4: "IPv6"}),
MultipleTypeField(
[
# IPv4
(IPField("addr", "0.0.0.0"), lambda pkt: pkt.atyp == 0x1),
# DNS
(DNSStrField("addr", ""), lambda pkt: pkt.atyp == 0x3),
# IPv6
(IP6Field("addr", "::"), lambda pkt: pkt.atyp == 0x4),
],
StrField("addr", "") # By default
),
]

它允许您根据条件使同一字段具有多种类型

关于python - 虚拟数据包字段 : how to handle a polymorphic protocole?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36138159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com