繁体   English   中英

Python从tcp套接字解压缩二进制流

[英]Python unpacking binary stream from tcp socket

好的,所以我认为熟悉Python是个好主意。 (我有过Java,php,perl,VB等经验,不是任何大师,但是中级知识)

所以我试图编写一个脚本,它将从套接字中获取数据,并将其转换为屏幕。 粗略的开始代码:

我的代码似乎正确地从套接字读取二进制信息,但我无法解压缩它,因为我无法访问原始结构。

我有这个流的输出与不同的程序,(这是非常写的,这就是我解决这个问题的原因)

当我打印出recv时,它就像这样......

b'L\x00k\x07vQ\n\x01\xffh\x00\x04NGIN\x04MAIN6Product XX finished reprocessing cdc XXXXX at jesadr 0c\x00k\x07vQ\n\x01\xffF\x00\x06CSSPRD\x0cliab_checkerCCheckpointed to XXXXXXXXXXXXXXXX:XXXXXXX.XXX at jesadr 0 (serial 0)[\x00l\x07vQ\n\x00\xff\x01\x00\x05MLIFE\x06dayendBdayend 1 Copyright XXXX XXXXXXX XXXXXXX XXXXX XXX XXXXXX XXXXXXXX.

从这个看,并将它与其他程序的输出进行比较,我猜测它应该被分解为......

b'L\x00k\x07vQ\n\x01\xffh\x00\x04NGIN\x04MAIN6Product XX finished reprocessing cdc XXXXX at jesadr 0'

有相应的信息

04-23
00:00:43
10
1
NGIN
MAIN
255
104
Product XX finished reprocessing cdc XXXXX at jesadr 0

现在,根据我的研究,看起来我需要使用“struct”并解压缩它,但是我不知道它的原始结构,我只知道它可以提供哪些信息,说实话,我我有一段时间搞清楚这一点。

我已经使用python解释器尝试解开线条的碎片,但这是一种令人沮丧的练习。

如果有人能帮助我开始,我会非常感激。

谢谢

好的。 我想我已经设法解码它,虽然我不确定中间的16位值。

这个Python 2.7代码......

from cStringIO import StringIO
import struct
import time

def decode(f):

    def read_le16(f):
        return struct.unpack('<h', f.read(2))[0]

    def read_timestamp(f):
        ts = struct.unpack('<l', f.read(4))[0]
        return time.ctime(ts)

    def read_byte(f):
        return ord(f.read(1))

    def read_pascal(f):
        l = ord(f.read(1))
        return f.read(l)

    result = []

    # Read total length
    result.append('Total message length is %d bytes' % read_le16(f))

    # Read timestamp
    result.append(read_timestamp(f))

    # Read 3 x byte
    result.append(read_byte(f))
    result.append(read_byte(f))
    result.append(read_byte(f))

    # Read 1 x LE16
    result.append(read_le16(f))

    # Read 3 x pascal string
    result.append(read_pascal(f))
    result.append(read_pascal(f))
    result.append(read_pascal(f))

    return result

s = 'L\x00k\x07vQ\n\x01\xffh\x00\x04NGIN\x04MAIN6Product XX finished reprocessing cdc XXXXX at jesadr 0c\x00k\x07vQ\n\x01\xffF\x00\x06CSSPRD\x0cliab_checkerCCheckpointed to XXXXXXXXXXXXXXXX:XXXXXXX.XXX at jesadr 0 (serial 0)[\x00l\x07vQ\n\x00\xff\x01\x00\x05MLIFE\x06dayendBdayend 1 Copyright XXXX XXXXXXX XXXXXXX XXXXX XXX XXXXXX XXXXXXXX.'

f = StringIO(s)
print decode(f)
print decode(f)
print decode(f)

... ...产量

['Total message length is 76 bytes', 'Tue Apr 23 05:00:43 2013', 10, 1, 255, 104, 'NGIN', 'MAIN', 'Product XX finished reprocessing cdc XXXXX at jesadr 0']
['Total message length is 99 bytes', 'Tue Apr 23 05:00:43 2013', 10, 1, 255, 70, 'CSSPRD', 'liab_checker', 'Checkpointed to XXXXXXXXXXXXXXXX:XXXXXXX.XXX at jesadr 0 (serial 0)']
['Total message length is 91 bytes', 'Tue Apr 23 05:00:44 2013', 10, 0, 255, 1, 'MLIFE', 'dayend', 'dayend 1 Copyright XXXX XXXXXXX XXXXXXX XXXXX XXX XXXXXX XXXXXXXX.']

时间戳已经超过了5个小时,所以我假设这是一个时区的事情。

我会说你使用struct是正确的,但结构很糟糕的是,你总是必须知道原始结构。

也许阅读tcp规范和isos会对所有人有所帮助,虽然现在仍然很难搞清楚:/

如果不知道二进制流的结构,虽然有足够的时间对其进行逆向工程,但很难解析,但您可能会接近或幸运。

虽然如果客户端程序使用pickle协议,你很幸运。

到目前为止,我只是反向工程代码,而不是二进制流,所以我远远不是你挑战的专家。 但是,我想分享一下我将如何解决你的问题的想法。 也许有人在那里发现有用(也许我自己在某个时间)。

TL; DR相关教育视频: Harald Welte,27C3

路线图

1.背景

获取有关程序的更多信息(编程语言,已知的序列化器/序列化格式,已知的怪癖等),域,该领域的任何规范,......

2.收藏

收集流中足够长的部分,或者,如果您知道消息的外观(任何消息的开头/消息结束标记),请收集一组适当的消息。 还收集参考程序的相应输出。

3.低垂的水果

尝试识别可在线路协议和相应输出中轻松发现的字符串和数字。 记下哪些部分不太清楚。

4.睁大眼睛

通过查找有线协议消息的重复和差异来扩展您的知识。 尝试将这些“有趣的点”与记录输出中的重复和差异相匹配。

5.假设

根据您的知识创建有关电线格式的假设。 特别要考虑步骤#1中可能对您有所帮助的信息。 此外,考虑什么可能是时间戳,序列号,校验和,消息标题,元数据,这样的东西。

6.验证

在代码中实现您的假设。 根据您记录的数据集运行它,以测试它是否按预期工作。 然后,反对一堆(可能更长)的新鲜样本 - 即使你以前没有见过 - 来支持你的假设。 如果出现故障,请返回步骤#5。

7.全力以赴

根据需要循环执行上述步骤,直到您可以提取所需的所有信息,甚至可以提取更多信息。

闭幕致辞

我认为,为了确保您对线路协议的理解是正确的,我们需要进行密集测试。 这包括A)单元测试,以确保您在测试新假设时不会破坏脆弱代码中的内容,并且B)在验证步骤中提到,将新样本投入代码并检查您的期望是否仍然有效。

但即便如此,你可能也错了。 即使经过全面测试,这也不能保证您的假设是正确的。 总是准备以新的方式思考,因为事实证明,看起来如此清晰的事实上是完全不同的。

如果有必要,可以疯狂地了解线路格式中可能隐藏的内容或者事物的排列和/或相关方式。

在我的这个可能无用的文本之后,让我完成一个视频: Harald Welte在27C3关于逆向工程的现实世界的RFID支付系统。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM