【问题标题】:Understanding Python struct.pack and binary input了解 Python struct.pack 和二进制输入
【发布时间】:2012-07-16 12:24:36
【问题描述】:

以下函数接受key 的二进制 4 字节密钥。 buf 是二进制输入,与 4 字节密钥进行异或。

def four_byte_xor(buf, key):
    #key = struct.pack(b">I", key) # removed for binary processing
    buf = bytearray(buf)
    for offset in range(0, len(buf), 4):
        for i, byte in enumerate(key):
            buf[offset + i] = chr(buf[offset + i] ^ ord(byte))
    return str(buf)

我从four_byte_xor() 中删除了key = struct.pack(b">I", key),以便通过str(p.payload.payload.payload)[:4]key 指定二进制数据。如果长度以 4 个字节结尾,这可以正常工作,否则会引发以下错误(请参阅下面的测试)。

以下是一些测试,其中包含一个输入 xor'd 与一个导致 00 的键,第一个成功:

'ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD'
'ABCD'

bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
'ABCD'

第二次测试不成功,以 A 或 1 个额外字节结束:

'ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDA'
'ABCD'
Traceback (most recent call last):
  File "./decode.py", line 36, in <module>
    process_packets()
  File "./decode.py", line 34, in process_packets
    out_buf.write(bin_four_byte_xor(pkt_payload, pkt_offset))
  File "./decode.py", line 22, in bin_four_byte_xor
    buf[offset + i] = chr(buf[offset + i] ^ ord(byte))
IndexError: bytearray index out of range

可以修改four_byte_xor() 以接受不同的buf 长度吗?

【问题讨论】:

  • linehexdump 的错误是因为该函数不返回十六进制值,而只是打印它们。我很高兴看到你放弃了这种方法。直接使用二进制数据作为键更有意义。 buff bytearray 的长度是 4 的精确倍数吗?如果没有,当你到达最后额外的 1-3 个字节时,你会得到一个超出范围的错误。
  • 虽然我已经测试了单个数据包并且它似乎工作正常,但它可能不是。当我尝试通过缓冲区提供多个数据包时,我收到超出范围的索引。它们应该是在迭代之间清除 bufkey 的东西还是自动的?
  • 这个问题接近于提供reproducible example,但不完全是。在您提及您尝试过的其他内容之前,您能否包括失败的精确代码未缩短(文件名除外)错误消息和函数调用(即像four_byte_xor(b'a', 42)) 这样程序就变成了一个独立的例子?如果您不知道确切的参数,您可以使用print(repr(buf)) 在实时系统中显示它们。
  • 似乎有一些差异。使用来自print(repr(buf)) 的输出更新问题。

标签: python scapy


【解决方案1】:

当然,您可以修改函数以接受不同的密钥长度。例如,像

def many_byte_xor(buf, key):
    buf = bytearray(buf)
    for i, bufbyte in enumerate(buf):
        buf[i] = chr(bufbyte ^ ord(key[i % len(key)]))
    return str(buf)

循环遍历键的所有字符(itertools.cycle 的模数版本)。这会产生

>>> many_byte_xor("AABAA", "AB")
'\x00\x03\x03\x03\x00'
>>> many_byte_xor("ABCDABCD", "ABCD")
'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> many_byte_xor("ABCDABCDA", "ABCD")
'\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> many_byte_xor("ABCDABCDAB", "ABCD")
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> many_byte_xor("ABCDABCDAB", "ABC")
'\x00\x00\x00\x05\x03\x01\x02\x06\x02\x03'

你想要哪个 IIUC。

【讨论】:

  • 为了提高效率,您可以在循环之前添加key = bytearray(key)key_len = len(key),然后可以将其中的分配简化为buf[i] = bufbyte ^ key[i % key_len]。因为bytearrays 只是小整数的可变序列,所以不需要ord()chr() 函数调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
相关资源
最近更新 更多