题目来源:2020安恒杯元旦月赛
题目名称:爆破鬼才
题目考点:ZIP注释信息+CRC32爆破+outguess隐写爆破+生日字典
给出的是一个压缩包,压缩包中有注释信息,注释信息给出了解压密码的范围:
使用ARCHPC爆破即可得到密码:abc123
解压之后里面又是一个压缩包,压缩包里面包含几个文件:
使用010 Editor查看具体信息之后发现360压缩给出的文件大小其实是不准确的,1.txt、2.txt、3.txt压缩前的大小分别为4 bytes、2 bytes、2 bytes,因此可以用CRC32碰撞破解这三个文件的内容,三个文件的内容组合起来便是压缩包的解压密码:Blowitup(下面给出了CRC32碰撞破解2.txt、3.txt的脚本,破解1.txt的脚本类似,只是字节数不同)
# -*- coding:utf-8 -*-
import binascii
def crack():
crcs = set([0xA28E7734, 0x4394EE70])
r = xrange(32, 127)
for a in r:
for b in r:
txt = chr(a)+chr(b)
crc = binascii.crc32(txt)
if (crc & 0xFFFFFFFF) in crcs:
print txt
if __name__ == "__main__":
crack()
除去作为解压密码的文件,还有hint.txt和Ziggs.jpg两个文件:
hint.txt文件的内容是:guess out my birthday
因此猜测是outguess隐写,密码需要通过生日字典爆破:
from os import system
from calendar import monthrange
year = 2012
month = 1
day = 1
key = ""
def inttostr(a, n):
ret = str(a)
while len(ret) < n:
ret = '0' + ret
return ret
def getNextKey():
global key
global year
global month, day
if key == '20200101':
return 0
day = day + 1
if day > monthrange(year, month)[1]:
day = 1
month += 1
if month > 12:
month = 1
year += 1
key = str(year) + inttostr(month, 2) + inttostr(day, 2)
return 1
def main():
while getNextKey():
cmd = "./outguess/outguess -k " + key + " -r Ziggs.jpg -t ./output/" + key +".txt"
system(cmd)
if __name__ == "__main__":
main()
因为outguess无法判断是否解密成功,但是我们知道flag文件大小应该是几十个字节,因此可以先把所有的结果计算出来,然后按大小排序,最后人工筛选。
当key = '20140224’的时候得到flag:flag{8322e7eed667c69f27ecbea5f96d86ca}