BUUCTF:zip

解压附件 发现许多同样大小的压缩包文件
image

image

发现压缩包内文件大小都是4
看起来像是CRC碰撞爆破

这里面压缩包有点多 写一个脚本进行多文件爆破

import zipfile

import binascii

import itertools

import string

from concurrent.futures import ProcessPoolExecutor

  

# --- 配置区域 ---

CHARSET = string.printable.strip() # 可根据需求缩小范围,如 string.digits + string.ascii_letters

MAX_LENGTH = 4                     # 碰撞的最大字节长度

ZIP_TEMPLATE = "out{}.zip"         # 压缩包命名模版

ZIP_COUNT = 68                     # 0 到 67,总共 68 个文件

# ----------------

  

def crc32_collision(target_crc, max_len):

    """尝试碰撞单文件的 CRC32"""

    for l in range(1, max_len + 1):

        for item in itertools.product(CHARSET, repeat=l):

            content = "".join(item).encode()

            if binascii.crc32(content) == target_crc:

                return content.decode()

    return None

  

def solve_single_zip(index):

    """处理单个压缩包的任务函数"""

    zip_name = ZIP_TEMPLATE.format(index)

    results = []

    try:

        with zipfile.ZipFile(zip_name, 'r') as zf:

            # 假设每个 zip 里只有一个文件,或者需要按内部文件名排序

            for info in zf.infolist():

                if info.file_size > MAX_LENGTH:

                    continue

                hit = crc32_collision(info.CRC, MAX_LENGTH)

                if hit:

                    results.append(hit)

                else:

                    results.append("[FAILED]")

        return index, "".join(results)

    except FileNotFoundError:

        return index, None

    except Exception as e:

        return index, f"Error: {e}"

  

def main():

    print(f"🚀 开始按顺序碰撞 out0.zip 到 out{ZIP_COUNT-1}.zip...")

    # 建立任务列表

    indices = range(ZIP_COUNT)

    # 使用进程池加速

    results_map = {}

    with ProcessPoolExecutor() as executor:

        # map 会异步执行,但我们通过返回 index 来保持顺序

        for index, content in executor.map(solve_single_zip, indices):

            if content is not None:

                results_map[index] = content

                print(f"✅ 已完成: {ZIP_TEMPLATE.format(index)} -> {content}")

  

    # 按照索引顺序排列并打印最终结果

    print("\n" + "="*20)

    print("最终拼接结果:")

    final_string = ""

    for i in range(ZIP_COUNT):

        part = results_map.get(i, "")

        final_string += part

    print(final_string)

    print("="*20)

if __name__ == "__main__":

    main()

最终拼接结果:

z5BzAAANAAAAAAAAAKo+egCAIwBJAAAAVAAAAAKGNKv+a2MdSR0zAwABAAAAQ01UCRUUy91BT5UkSNPoj5hFEVFBRvefHSBCfG0ruGnKnygsMyj8SBaZHxsYHY84LEZ24cXtZ01y3k1K1YJ0vpK9HwqUzb6u9z8igEr3dCCQLQAdAAAAHQAAAAJi0efVT2MdSR0wCAAgAAAAZmxhZy50eHQAsDRpZmZpeCB0aGUgZmlsZSBhbmQgZ2V0IHRoZSBmbGFnxD17AEAHAA==

base64解码
image

解码后,保存为dat文件 010 打开

image

依稀可以看出

flag.txt
fix the file and get the flag

可以知道这是需要修复文件 来得到flag,但是目前不知道文件头

https://vxhly.github.io/views/windows/file-header-and-tail.html

可以对比 helloctf上的进行补全

https://hello-ctf.com/hc-misc/Archivefile/#rar

可以观察到rar的文件为是0700
在文件头加上 **52 61 72 21 1A 07 00

image

image

在注释处发现flag

flag{nev3r_enc0de_t00_sm4ll_fil3_w1th_zip}
posted @ 2026-04-05 20:54  Sakur_a  阅读(0)  评论(0)    收藏  举报