如何控制Scapy中协议头/消息的大小?

2024-05-02 04:56:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为Scapy创建ZMTP协议,但无法找到如何有效地将字段和数据包填充到某个字节大小。在

我试着在Scapy中创建一个新的协议,即这里描述的问候语https://www.codeproject.com/Articles/863889/ZeroMQ-Diving-into-the-Wire

class ZmtpGreeting(Packet):
    name = "ZMTP Greeting"
    fields_desc = [
        XByteField("signature", "ff00000000000000117f"),
        XByteField("version_major", "03"),
        XByteField("version_minor", "00"),
        PadField(XByteField("security_mechanism", "4e554c4c"), 20, padwith="\x00"),
        XByteField("as_server", "00"),
    ]

问题1: 上面的实现似乎没有为security_mechanism字段包含最多20个字节的填充:

^{pr2}$

整个数据包也应该被填充到64个八位字节,我不知道如何在协议中包含它(或者作为它之外的填充)。在

问题2: 我无法使用raw(..)或len(..),因为它们失败并出现以下错误:

^{3}$

问题3: 这是在它自己的python文件中的layers下,但只有当我直接将它粘贴到Scapy控制台中时才起作用。在

我已经看过Scapy的文档,但是还没有找到如何实现这个目标。提前谢谢!在


Tags: httpscom协议字节versionwww数据包articles
2条回答

Q : how to effectively pad a field and the packet up to a certain byte size.

python方面,您可以始终import struct并使用其所有位字段的操作进行操作,使用<mask>-元语言控制的值到结果位字段的智能映射(以两种方式中的任何一种使用{.pack()|.unpack()}-方法),如struct.unpack( aMSG_STRUCT_MASK, aMSG )

如果要在决胜局中使用部分校验和,则可能需要一个“分层”(逐步)程序集ZMTP:RFC兼容包有效载荷。在

这包括多个代码路径,用于可能特定于版本的有效负载程序集处理规则,这些规则是从不同的ZMTP:RFC版本/版本/模式-操作。在

也许从铅笔和纸开始,根据需要绘制所有位域的细节ZMTP:RFC和检查他们的所有实现(这是一个残酷的手动方法,然而,这个清单+检查表实际上可以把你省下来作为最后的手段,因为它非常有效而且非常正统-未经检查的强制性要求意味着“被遗忘”的部分实现+不兼容/错误的实现可以逐个功能进行测试,所以没有人会被放任不管或是被错误地验证过——这听起来可能很无聊,但却是一种拯救生命的习惯。在

Q : Problem 2:

是不确定的,因为不可重复,但是进一步的调试工作将显示根本原因(尝试使用<pyObject>s,使用+-运算符,将<pyObject>-从对上述推荐工具的调用中获得,struct.pack()-方法:
struct.pack( self.<anInstanceAttributeMASK>, self.<aMethod>( <pyObject>, <pyObject>) )

Q : Problem 1: 64-octet padded / word-aligned / null-terminated

所有这些由详细的ZMTP/RFC规范控制的需求都将得到满足,struct.pack()将满足这些要求,只要设置正确,<aPackMASK>-s将参与ZMTP有效载荷内容包数据集合。在

最好的评论ZMTP:指定RFC细节(长度、对齐、填充、终止、(部分)校验和)确实符合要求(即使对于转角情况),并纠正/修改发现的所有缺失特征。在


如果大整数元素无法通过格式化来处理,则可以将大的块拆分为一系列的几个较小的块,以避免在ScaPy硬编码函数的任何部分中对格式化/分组汇编执行任何可能失败的int/string操作,如下所示:

|>>> sig_num= 0xff00000000000000117f
|>>> sig_num
1204203453131759529496959L
|>>> "{0:x}".format( sig_num )
'ff00000000000000117f'
|>>> "{0:b}".format( sig_num )
'11111111000000000000000000000000000000000000000000000000000000000001000101111111'
|>>> len( "{0:b}".format( sig_num ) )
80
|>>> "{0:0>20b}{1:0>20b}{2:0>20b}{3:0>20b}".format( sig_num / 2**60,
                                                    sig_num % 2**60 / 2**40,
                                                    sig_num %         2**40 / 2**20,
                                                    sig_num %                 2**20
                                                    )
'11111111000000000000000000000000000000000000000000000000000000000001000101111111'
  • 首先,在Scapy中,X[...]字段只是为了方便用户使用。这意味着您不能使用字符串作为默认值:Scapy只处理int(除了特殊字段、数据包字段、字符串字段…)。将这些值更新为数字表示将修复Q2
  • 我怀疑ByteField能取这么高的值:/
  • 要添加最后的填充,请查看post_dissection

相关问题 更多 >