【攻防世界】beginners-luck

给你一个加密过的图片和加密用的 py,加密过程就是用一个长度为 24 的 key 循环异或一下图片的字节流

这题与其说是密码题不如说是 misc 题

 png 的前 16 位都是定死的,89 50 4e 47 0d 0a 1a 0a 是固定文件头,接下来的第一个数据块必须是关键数据块

关键数据块的组成部分:

00 00 00 0d 表示数据块长度为13 ,这个不会变

49 48 44 52 是 IHDR 标识,这个也是死的

接下来 8 位,前 4 位是宽,后 4 位是高

最后 5 位中第一位是色深,第二位是颜色类型,接下来一般都是三个 00

在关键数据块后还有 4 位 CRC 校验码

那么可以看到,前 24 位中只有宽和高的 8 位不是死的,key 的 16 位可以直接解出来

直接爆破宽高得 key 然后解密看图得方式是不可能的

不过可以发现,出题人很良心地让 key 的长度刚好到高的 4 位这里停下来,那么也就是说关键数据块的末 5 位和 CRC 校验码都是可以解的

那么就可以枚举宽高,然后快速通过 CRC 校验来验证啦

爆破代码:

 1 crc = 0x67b15614
 2 for i in range(0x000, 0xfff):
 3     for j in range(0x000, 0xfff):
 4         width = struct.pack('>i', i)
 5         height = struct.pack('>i', j)
 6         # print(width, height)
 7         data = b'x49x48x44x52' + width + height + b'x08x02x00x00x00'
 8         crc2 = binascii.crc32(data) & 0xffffffff
 9         if crc2 == crc:
10             print(width, height)
View Code

坑:

还是常见坑,python 对二进制流的处理字词得不是很好

如果你想把一个 str 转成 bytes ,最好这样:

r = b''
for i in t:
r = r + ord(i).to_bytes(1, byteorder='big')
原文地址:https://www.cnblogs.com/cdcq/p/14274759.html