Article Summary
GPT 4

zipfile

常用模块

ZipFile
import zipfile
f = zipfile.ZipFile(case.zip,'r') #以可读方式创建一个ZipFile对象
f_name = f.namelist() #获取zip对象内所有文件的名称列表
f_info = f.getinfo(name) #获取zip对象内指定文件的信息
f_infolist = f.infolist() #获取zip对象内所有文件的信息,返回列表
f.extract(name, path, pwd) #解压zip对象内指定文件到指定路径中,密码为pwd
f.printdir() #将zip对象内的信息打印到控制台上
Zipinfo
import zipfile, os
zipFile = zipfile.ZipFile(os.path.join(os.getcwd(), 'duoduo.zip'))
zipInfo = zipFile.getinfo('name') #zip对象内的文件
print ('filename:', zipInfo.filename)  #获取文件名称
print ('date_time:', zipInfo.date_time)   #获取文件最后修改时间。返回一个包含6个元素的元组:(年, 月, 日, 时, 分, 秒)
print ('compress_type:', zipInfo.compress_type) #压缩类型
print ('comment:', zipInfo.comment)   #文档说明
print ('extra:', zipInfo.extra)    #扩展项数据
print ('create_system:', zipInfo.create_system) #获取创建该zip文档的系统。
print ('create_version:', zipInfo.create_version) #获取 创建zip文档的PKZIP版本。
print ('extract_version:', zipInfo.extract_version) #获取 解压zip文档所需的PKZIP版本。
print ('extract_version:', zipInfo.reserved) # 预留字段,当前实现总是返回0。
print ('flag_bits:', zipInfo.flag_bits) #zip标志位。
print ('volume:', zipInfo.volume) # 文件头的卷标。
print ('internal_attr:', zipInfo.internal_attr) #内部属性。
print ('external_attr:', zipInfo.external_attr) #外部属性。
print ('header_offset:', zipInfo.header_offset) # 文件头偏移位。
print ('CRC:', zipInfo.CRC) # 未压缩文件的CRC-32。
print ('compress_size:', zipInfo.compress_size) #获取压缩后的大小。
print ('file_size:', zipInfo.file_size) #获取未压缩的文件大小。
zipFile.close() 

题目

[GDOUCTF 2023]Matryoshka

本题是一个压缩包套娃。

password1000.txt与Matryoshka1000.zip

其中每一层数字进行递减

eightfivezeroninefivetwosevenplusonesevenzerosevenfoursevensevenfourtwoplusfouronezerothreethreezerotimesthreefiveonesixfiveseveneighteightsevenplusfiveonesevennineonefivethreeeight

密码为算出的结果。但是密码文件的运算逻辑不是平常做的那种。而是,固定下来,从左往右进行运算

import zipfile
import os
import re

def get_password(next_password_file):
    with open(next_password_file, 'r') as f:
        data = f.read().strip()
    replace_list = [["zero", "0"], ["one", "1"], ["two", "2"], ["three", "3"],
                    ["four", "4"], ["five", "5"], ["six", "6"], ["seven", "7"],
                    ["eight", "8"], ["nine", "9"], ["plus", "+"], ["times", "*"],
                    ["minus", "-"], ["mod", "%"]]
    for re_list in replace_list:
        data = data.replace(re_list[0], re_list[1])

    nums = re.findall(r"\d{1,}", data)//匹配所有数字
    valid_nums = []
    for num in nums:
        valid_nums.append(str(int(num)))
    for i in range(len(nums)):
        data = data.replace(nums[i], valid_nums[i])//将数字转化为字符串,并将其添加到对应的位置

    list1 = ['+', '-', '*', '%']
    count_s = 0
    for l in list1:
        counts = data.count(l)
        count_s += counts
    data = '(' * count_s + data
    list2 = [['+', ')+'], ['-', ')-'], ['*', ')*'], ['%', ')%']]
    for li in list2:
        data = data.replace(li[0], li[1])
    password = abs(eval(data))
    return password


def zip_file(next_zip, password, next_password_file):
    zf = zipfile.ZipFile(next_zip, 'r')
    name_list = zf.namelist()
    zf.extractall(path='.', pwd=password.encode('utf-8'))
    zf.close()
    os.remove(next_password_file)
    os.remove(next_zip)
    next_password_file, next_zip = name_list[0], name_list[1]
    return next_password_file, next_zip


if __name__ == '__main__':
    next_password_file = 'password1000.txt'
    next_zip = 'Matryoshka1000.zip'
    while True:
        try:
            password = str(get_password(next_password_file))
            next_password_file, next_zip = zip_file(next_zip, password, next_password_file)
        except Exception as e:
            print(e)
            break

参考链接

https://www.cnblogs.com/ManyQian/p/9193199.html