附件链接: https://pan.baidu.com/s/1oTMiP2q6pp4aIsqqHk1_Fg
提取码: f6p8

little

不算难,但是难得没有套娃的题,做着很舒服

题目分析:

解压是一个img文件

winhex打开可以发现secondf.png

是flag的第二部分,这一张图也可以直接使用binwalk命令进行分离

binwalk继续查看img文件

可以看到有一个kgb文件,百度易知是压缩格式的一种

使用DiskGenius磁盘分区助手对img进行挂载即可得到FIRSTF.kgb

下载kgb解压器,解压后得到firstf.ogg

ogg是一个开源音频格式,直接听就可以得到第一部分flag

c0me_wi4h_f4t_m4n_

猜测还有第三部分,搜索一下,果然有,这一部分要感谢EDS师傅提供的提取方法

使用winhex进行提取

工具→磁盘工具→通过文件类型恢复,选中MP4格式自动提取

得到MP4

完整flag

SUSEC{c0me_wi4h_f4t_m4n_t0_7h3_3nd_0f_t4i3_sUsEc_journey}

perceptron

Simulating the human brain is currently impossible, but perceptron is trying to do that!

Hint 1: There are many same sizes IDAT chunks in perceptron, are all of them necessary?
Hint 2: There are other PNGs too. Try to recover them.

题目分析:

lsb分析没看出什么问题,但是使用zsteg自动分析可以发现zlib区块

pngcheck可以发现有很多IDAT块,不太正常。

共计18个IDAT区块
PNG文件结构分析 ---Png解析 - DoubleLi - 博客园
PNG文件结构分析 ---Png解析为了实现更高级的应用,我们必须充分挖掘PNG的潜力。PNG的文件结构根据PNG文件的定义来说,其文件头位置总是由位固定的字节来描述的:十进制数137 80 78 7

搜索网上的教程,可以发现有两种常见的关于这种情形的隐写,一种是跟zlib区域有关,另一种是IDAT区块有关,但是有些教程是错误的,写wp的人本身都没有理解,纯粹就是乱写wp,甚至有说IEND区块size为0是有问题的,莫名其妙...

IEND块必须最后出现。它标志着 PNG 数据流的结束。块的数据字段一定为空

要搞清楚这些,我觉得核心还是要搞清楚zlib跟IDAT区块的关系,因为我的英语水平有限,所以下面我只会简要阐述下我的理解,仅供参考,建议以官方文档为准

IDAT图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像。
png官方文档
IDAT中zlib压缩官方文档
机翻

划一下重点

  1. 图片中zlib压缩使用固定Huffman 编码的 LZ77 压缩数据或使用自定义 Huffman 代码编码的 LZ77 压缩数据。最终块中的标记位将其标识为最后一个块,允许解码器识别压缩数据流的末尾。
  2. 终止的zlib检查值完全可以在IDAT块之间分割(zlib可以分割IDAT区块),完整的图像数据由一个单独的zlib datastream表示,它存储在一些IDAT块中;一个译码器,如果超过这个是不正确的
  3. 除了IDAT区块,iTXt、zTXt和iCCP区块都会使用zlib压缩,但是这些数据流不会拆分为块。每个iTXt、zTXt或iCCP块包含独立的 zlib 数据流。

举例使用第一个IDAT区块来分析一下

BF CE D9 46是图片的CRC32(与IDAT区块的crc算法不同)
红框选中的4个字节是描述该IDAT块内容大小的,07 F9转成十进制是2041
49 44 41 54是IDAT的数据块名,78 9C是zlib的标志位

查询下zlib的位置,记住标志位是78 9C,会发现有三个

前文已经划出重点了,一个png图片不会在IDAT中存在多个zlib,经过pngcheck也是可以判断不存在其他可能存在zlib部分的区块,所以,这3个zlib都存在于IADT中。

盲生你发现了华点!!!

这里肯定有问题了。

我们分别找到三个zlib的位置,然后用第二个或者第三个zlib替换第一个zlib

之前提过末尾四位是zlib的校验位

截图这个是第三个zlib区域,因为刚好连接着IEND块,所以分析起来方便一点,010可以很方便的为我们查看zlib末尾提供帮助,判断哪部分是IEND,哪部分是IDAT

4D 4D 2A F3就是这块zlib的校验位,也就是zlib尾。第一第二的校验位不一定是这个。

我们先删除从29h3047h的zlib部分看看效果(IDAT出现多个zlib这种只会识别第一个,所以删除第一个之后识别的就是第二个zlib部分)

得到的图片是乱码,一般这种情况可以怀疑是不是图片宽高不对。

使用FzWjScJ 师傅的脚本,自动爆破宽高,生成图片

需要注意的是,这里的宽高并非是图片本身的宽高,如果校验CRC32你会发现宽高是错误的,图片的核心数据部分是IDAT,这里我们只是借用了png的其他区块让图片显示而已。
#python3
import binascii
from Crypto.Util import number
p = open('2.png','rb').read()
# print(p[0x14:0x17]+chr(0xaf).encode()[-1:])
count = 0
for a in range(0x00,0xff):
    data = p[:0x12] + chr(0x04).encode() + chr(a).encode()[-1:] + p[0x14:0x16] + chr(0x00).encode() + chr(0xa0).encode()[-1:]
    # print(binascii.crc32(data))
    p2 = p[:0x12] + chr(0x04).encode() + chr(a).encode()[-1:] + p[0x14:0x16] + chr(0x00).encode() + chr(0xa0).encode()[-1:] + p[0x18:0x1d] + number.long_to_bytes(binascii.crc32(data)&0xffffffff) + p[0x21:]
    p1 = open('te/'+str(count)+'.png','wb')
    count += 1
    p1.write(p2)
    p1.close()

分辨率:1132x160

第三个zlib也是一样的方法。flag内容一样,但是宽高不一样,可以自己试试。

还有一种方法是解压zlib,然后用gimp原始数据打开,更加方便调试


写在后面:

坦白讲写完这篇文章我还是有点懵的,主要是宽高的问题,原来是经常遇到的只有高度不对的情况,结合tweakpng很容易试出来正确的高度,但是这次遇到两个都有的错误情况就没用了,电脑的python3环境又出了点问题,很烦。

还有的题型是解压zlib可以得到数据,解压算法分析可以参看这篇

【数据压缩】LZ77算法原理及实现 - Treant - 博客园
1. 引言 "【数据压缩】LZ77算法原理及实现" "【数据压缩】LZ78算法原理及实现" LZ77算法是采用字典做数据压缩的算法,由以色列的两位大神Jacob