下载回来一个out.png,binwalk跑一下,可以提取出来一个python脚本:
import random
from Crypto.Util import number
a = open('flag.png','rb').read()
p = [a.find(b'IDAT')]
while 1:
if a.find(b'IDAT',p[len(p)-1]+1) != -1:
p.append(a.find(b'IDAT',p[len(p)-1]+1))
else:
break
b = open('out.png','ab')
b.write(a[:p[0]-4])
for i in p:
l = number.bytes_to_long(a[i-4:i])
b.write(a[i-4:i])
C = a[i:i+4]
b.write(C)
d = a[i+4:i+4+l]
f_d = b''
s = random.randint(0,0x40)
for j in d:
f_d += number.long_to_bytes(j^s)
if i == p[0]:
b.write(d)
else:
b.write(f_d)
c = a[i+4+l:i+4+l+4]
b.write(c)
if i == p[-1]:
b.write(a[i+4+l+4:])
b.close()
具体逻辑是随机一个数和每个IDAT块异或,抄一下大佬的解密脚本:https://blog.csdn.net/qq_42880719/article/details/117389569
import random
import zlib
from Crypto.Util import number
f_d = b''
a = open('out.png','rb').read()
p = [a.find(b'IDAT')]
while 1:
if a.find(b'IDAT',p[len(p)-1]+1) != -1:
p.append(a.find(b'IDAT',p[len(p)-1]+1))
else:
break
b = open('flag.png','wb')
b.write(a[:p[0]-4])
for i in p:
l = number.bytes_to_long(a[i-4:i])
b.write(a[i-4:i])
C = a[i:i+4]
b.write(C)
d = a[i+4:i+4+l]
c = a[i+4+l:i+4+l+4]
for j in range(0,256):
f_d = b''
f_d += C
for k in d:
f_d += number.long_to_bytes(k^j)
if zlib.crc32(f_d)==number.bytes_to_long(c):
break
if i == p[0]:
b.write(d)
else:
b.write(f_d[4:])
b.write(c)
if i == p[-1]:
b.write(a[i+4+l+4:])
b.close()
跑出来一张图片后,修改高度就可以看到flag。