Tags:ZIP套娃
,QRCODE
0x00. 题目
附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件
附件名称:202003_MRCTF_千层套娃.zip
0x01. WP
01. 打开压缩文件发现hint信息
发现是zip套娃,需要通过python脚本进行自动化解压
Hint:密码均为四位数字 和压缩包名字有关联哦
Python真好用233
autoUnzip.py
import zipfileimport osimport redef find_next_zip():"""查找当前目录及子目录中下一个四位数字命名的ZIP文件"""for root, dirs, files in os.walk('.'):for file in files:if re.match(r'^\d{4}\.zip$', file):return os.path.join(root, file)return Nonedef extract_zip(i,current_zip, password):"""解压指定ZIP文件并使用给定密码"""try:with zipfile.ZipFile(current_zip) as zf:zf.extractall(pwd=password.encode('utf-8'))print(f"第{i}层,解压成功: {current_zip} ,密码: {password}")return Trueexcept zipfile.BadZipFile:print(f"第{i}层,错误: {current_zip} 不是一个有效的ZIP文件")return Falseexcept RuntimeError as e:if 'password' in str(e).lower():print(f"第{i}层,密码错误: {current_zip} - 预期密码: {password}")else:print(f"第{i}层,解压失败: {e}")return Falsedef main(start_zip):current_zip = start_zipmax_attempts = 5000 # 防止无限循环for _ in range(max_attempts):# 提取密码(文件名不含扩展名)password = os.path.splitext(os.path.basename(current_zip))[0]# print(current_zip)# 执行解压if not extract_zip(_,current_zip, password):break# 删除已处理的ZIP文件以保持清洁(可选)os.remove(current_zip)# 查找下一个符合条件的ZIPnext_zip = find_next_zip()if not next_zip:print("已找到最内层文件,结束解压流程")breakcurrent_zip = next_zipprint(f"最终保留的文件: {current_zip}" if os.path.exists(current_zip) else "所有压缩文件已处理完毕")if __name__ == "__main__":initial_zip = "0573.zip" # 初始文件名,按实际修改if os.path.exists(initial_zip):main(initial_zip)else:print(f"初始文件 {initial_zip} 不存在!")
别的师傅的精简脚本 unzip.py
import zipfile
name = '0573'
while True:fz = zipfile.ZipFile(name + '.zip', 'r')fz.extractall(pwd=bytes(name, 'utf-8'))name = fz.filelist[0].filename[0:4]fz.close()
2. 最后得到压缩包qr.zip
,里面是个文本文件
包含了40000行信息,只有(255, 255, 255)
和(0, 0, 0)
,初步判断是个二维码,需要python脚本构图并读取
autoQR.py
# Usage: python qr.py qr.txtfrom PIL import Imageimport reimport argparse # 新增参数解析模块from pyzbar.pyzbar import decode # 新增二维码识别模块from pyzbar.pyzbar import ZBarSymbol # 新增符号类型限定def parse_pixel(line):"""解析单行像素数据,返回(r, g, b)元组"""matches = re.findall(r'\d+', line)if len(matches) != 3:raise ValueError(f"无效的像素格式: {line}")r = min(max(int(matches[0]), 0), 255)g = min(max(int(matches[1]), 0), 255)b = min(max(int(matches[2]), 0), 255)return (r, g, b)def txt_to_image(input_file, output_file="output.png"):"""将文本像素文件转换为图片并进行二维码解析"""try:with open(input_file, 'r') as f:lines = [line.strip() for line in f if line.strip()]if len(lines) != 200*200:raise ValueError(f"文件应包含40000行数据,实际检测到{len(lines)}行")img = Image.new('RGB', (200, 200))pixels = img.load()for index, line in enumerate(lines):y = index // 200x = index % 200pixels[x, y] = parse_pixel(line)img.save(output_file)print(f"图片已生成:{output_file}")# 新增二维码识别功能 ################################print("\n开始二维码扫描...")detected_qrcodes = decode(img, symbols=[ZBarSymbol.QRCODE] # 仅检测QR Code)if detected_qrcodes:print("发现二维码内容:")for qr in detected_qrcodes:content = qr.data.decode('utf-8')print(f"• 位置 {qr.rect} -> {content}")# 可选:保存识别到的二维码内容到文本文件with open('qrcode_content.txt', 'w') as f:f.write(content)else:print("未检测到有效二维码")# ################################################except FileNotFoundError:print(f"错误:输入文件 {input_file} 不存在")except ValueError as ve:print(f"数据错误:{ve}")except Exception as e:print(f"运行时异常:{e}")def main():parser = argparse.ArgumentParser(description='像素转图片+二维码识别')parser.add_argument('input', help='输入文本文件路径')parser.add_argument('-o', '--output', default='output.png',help='输出图片路径,默认output.png')args = parser.parse_args()txt_to_image(args.input, args.output)if __name__ == "__main__":main()# MRCTF{ta01uyout1nreet1n0usandtimes}
别的师傅的精简脚本 qr.py
import itertools
from PIL import Imagemax = 200
file = open("qr.txt", "r")img = Image.new("RGB", (max, max))
for y, x in itertools.product(range(max), range(max)):pixel = eval(file.readline())img.putpixel([x, y], pixel)img.show()