1.png_master

附件只有一张 png,先拖进winhex看看,发现文件尾有明显base64特征字符,解码得到:

Congratulations on finding the first paragraph of flag, but the understanding of png is just beginning.
flag1:DASCTF{2fd9e9ff-e27

看看图片属性,发现位深32,判断图片为RGBA模式,先用zsteg试了下没出东西,再仔细观察图片,发现图片上端有明显的灰色区域,判断应该是Alpha通道存在隐写:

得到flag2:

d-5405-c5f5

将flag.png拖到010Editor里面可以看到输出中直接Error了,观察到在chunk[4] IDAT数据块未满的情况下还有chunk[5] IDAT数据块,显然这一块是多出来的部分:

同时注意到有zlib文件头 78 9C ,而每个 PNG 图片都包含 zlib 压缩过的图像数据,这块应该是另外一张png的数据部分,头尾照搬原png,然后爆破宽高,可以拿到隐藏的图片:

import zlib
import struct
import argparse
import itertools
from PIL import Image
import os
#关于PNG格式可以自行上网查阅资料,资料还是挺丰富的,完全足够了解PNG文件格式

index = 0
filename = 'flag.png'
with open(filename, 'rb+') as file:
    bin_data = file.read()
    for width, height in itertools.product(range(498,510), range(498,510)): 
        file.seek(0x12)
        file.write(struct.pack('!H', width))
        file.flush()
        file.seek(0x16)
        file.write(struct.pack('!H', height))
        file.flush()
        for colortype in [2,6]: ## 颜色类型:2:真彩色图像; 6:带α通道数据的真彩色图像
            file.seek(0x19)
            file.write(chr(colortype).encode())
            file.flush()
            crc32_data = crc32_data = b"\x49\x48\x44\x52\x00\x00" + struct.pack('!H', width) + b"\x00\x00" + struct.pack('!H', height) + b"\x08" + chr(colortype).encode() + b"\x00\x00\x00"
            crc32 = zlib.crc32(crc32_data)
            file.seek(0x1D)
            file.write(crc32.to_bytes(4,'big'))
            file.flush()
            file.seek(0x00)
            try:
                index += 1
                f = open("./FINAL/hidden{}.png".format(index),"wb+")
                f.write(file.read())
                f.close()
                img = Image.open("./FINAL/hidden{}.png".format(index))
                img.show()
                img.close()
            except OSError:  
                try:
                    os.remove("./FINAL/hidden{}.png".format(index))
                except PermissionError:
                    pass

在网上没找到爆破 未知crc且未知图片宽高 的png脚本,自己写了一个,但是有点问题,只能小范围爆破宽高,靠近正确宽高的时候会爆出很多图片,其实用起来也不方便,之后再看看有没有办法优化

下面是上述脚本运行后结果,这么点范围都有这么多图片,稍微大一点就更不用说了,还是挺麻烦的:

看图拿到flag3:

a19131f86216}

三段合成完整flag:

DASCTF{2fd9e9ff-e27d-5405-c5f5a19131f86216}

2.EZ_zip

附件只有一个zip文件,直接解压会报错,想到应该是zip文件格式出了问题

010Editor打开,先从文件头开始看,对着zip格式查查,或者拿个正常zip文件对比着看,发现在001Ah处的 FileNameLength 不对,应为7,不过这一处问题好像不影响解压(

中间数据看不出什么东西来,直接看文件尾

如果是正常的zip文件,尾部会有一块叫dirEntry的部分,显然这个文件没有,对比着正常文件看,发现有两处问题

首先 FileNameLength为7,其次是 COMPTYPE deCompression 的问题,关于这个数值为何是8,是因为文件头也有这部分内容:

这部分内容是关于压缩方式的,将文件尾对应部分改为8即可:

接下来就可以正常解压得到320.zip,能看到其中有注释 just a byte,应该指密码为一字节

同时考虑到320.zip中有319.zip,应该总共是有320个压缩包,加上字节密码会有不可打印字符,无论如何都要用到脚本来批量解压缩:

import pyzipper
key1 = ""  #获取key是解压后的问题
for i in range(320,0,-1):
    zip_file_path = "待解压文件目录" + "\{}.zip".format(i)
    with pyzipper.AESZipFile(zip_file_path) as extracted_zip:
        for pwd in range(0x00,0x100):  #一字节密码ASCII值范围
            password = bytes([ord(chr(pwd))])  #转字节
            try:
                extracted_zip.extractall(path=r"解压得到文件的保存目录",pwd=password)
                key1 += hex(pwd).replace("0x","").rjust(2,"0")
                break
            except:
                pass

key2 = ""  #key逆置是因为按照正常解压顺序得到的key无法解AES
for i in range(len(key1)//2):
    key2 += key1[len(key1)-2*i-2:len(key1)-2*i]
    
with open("key.txt","w") as f:
    f.write(key2)

解压后能得到 320个zip文件 和 1个AES-ECB.txt,内容为:

64ZpNmbv2Hg4Jj9bH8Kv6D3OBliD9hgyI3vZWfMDJs2TcEwVnBmH/zkBtPBE3g8e

the key may be on your journey?

根据提示回头找key,上述脚本中已获取,可以发现key.txt中有重复区段,整理后如下:

c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11
c64e5e2225444a9da66b0f28ad718f798cffa70a48124ec5873a610c5899bb11

拿去解AES可以得到flag: