学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1157

主题

[Misc] Happy_puzzle

发表于 2020-1-5 22:58:14 | 查看: 3353| 回复: 0

相关题目:

♦ Happy_puzzle

原理知识
1) PNG便携式网络图形是一种无损压缩的位图片形格式,其设计目的是试图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。PNG使用从LZ77派生的无损数据压缩算法,一般应用于JAVA程序、网页或S60程序中,原因是它压缩比高,生成文件体积小。
解题过程
  • 下载题目到本地,打开压缩包发现很多data文件如下图所示:
图1 data文件
  • 由文件夹中的info.txt可知,这些data数据块是由图片格式为400 X 400的png图片拆卡得到的,
  • 分析
    复制*.data (10240 * N + 5214)
    ,推测这些data是IDAT 数据块,编写脚本将数据块组合到一起,部分脚本如下图所示:
exp.py
#!/usr/bin/env python2
# -*- coding:utf-8 -*-
"""
    Author : Virink <virink@outlook.com>
    Date   : 2019/08/28, 18:00
"""

import os
import sys
import binascii
import zlib

OUTPUT = 'puzzle'


def bin2hex(data):
    return binascii.b2a_hex(data)


def hex2bin(data):
    return binascii.a2b_hex(data)


def dec2bin(data, l=1):
    l = l / 2
    if l == 4:
        return hex2bin("%08x" % int(data))
    else:
        return hex2bin("%02x" % int(data))


def bin2dec(data):
    return int(bin2hex(data), 16)


def crc32(chunkType, chunkData):
    return dec2bin(binascii.crc32(chunkType + chunkData), 8)


def genIHDR(w, h):
    width = dec2bin(w, 8)
    height = dec2bin(h, 8)
    bits = dec2bin(8)
    color_type = dec2bin(2)
    compr_method = filter_method = interlace_method = dec2bin(0)
    chunkData = width+height+bits+color_type + \
        compr_method+filter_method+interlace_method
    res = dec2bin(len(chunkData), 8)+b'IHDR' + \
        chunkData+crc32(b'IHDR', chunkData)
    print([res])
    return res


def genIDAT(data):
    _c = zlib.crc32(b'IDAT'+data)
    if _c < 0:
        _c = ~_c ^ 0xffffffff
    _crc = dec2bin(_c, 8)
    return dec2bin(len(data), 8) + b'IDAT' + data + _crc


def merge_png(width, height, names, output="tmp.png"):
    header = hex2bin("89504E470D0A1A0A")
    ihdr = genIHDR(width, height)
    idat = []
    for name in names:
        f=open("%s/%s" % (OUTPUT, name),'rb')
        data = f.read()
        idat.append(genIDAT(data))
        f.close()
    idat = b''.join(idat)
    iend = hex2bin("00000000" + "49454E44" + "AE426082")
    with open(output, 'wb') as f:
        f.write(header+ihdr+idat+iend)


if __name__ == '__main__':
    fs = ["blczioav.data", "ciaoxptf.data", "csizrgxn.data", "dwelszrk.data", "fhnkotmb.data", "fkjhepcs.data", "gpiuezjw.data", "hbctmwqj.data", "jlxphwfm.data", "jrbiznkl.data", "jtxsbevz.data", "kczwtlrd.data", "lstjobzi.data",
          "mrxtfkzj.data", "oaeqnubi.data", "pyusgabf.data", "rnydeiho.data", "tihzkoyu.data", "uilqywot.data", "uozjmdnl.data", "wgkapjbh.data", "xufbyndk.data", "xufnmacj.data", "ycqzmbrw.data", "yscijlzx.data", "yvxmeawg.data"]
    merge_png(400, 400, ['yvxmeawg.data',
                             'rnydeiho.data','uozjmdnl.data',
                             "fhnkotmb.data",'jlxphwfm.data',
                             'yscijlzx.data','ciaoxptf.data',
                             'blczioav.data','jtxsbevz.data',
                             'lstjobzi.data','pyusgabf.data',
                             'wgkapjbh.data','xufbyndk.data',
                             'csizrgxn.data','oaeqnubi.data',
                             'gpiuezjw.data','tihzkoyu.data',
                             'hbctmwqj.data','ycqzmbrw.data',
                             'fkjhepcs.data','kczwtlrd.data',
                             'dwelszrk.data','uilqywot.data',
                             'xufnmacj.data','jrbiznkl.data',
                             'mrxtfkzj.data'], "%s.png" % "flag")


    # for f in fs:
    #     merge_png(400, 400, ['yvxmeawg.data',
    #                          'rnydeiho.data','uozjmdnl.data',
    #                          "fhnkotmb.data",'jlxphwfm.data',
    #                          'yscijlzx.data','ciaoxptf.data',
    #                          'blczioav.data','jtxsbevz.data',
    #                          'lstjobzi.data','pyusgabf.data',
    #                          'wgkapjbh.data','xufbyndk.data',
    #                          'csizrgxn.data','oaeqnubi.data',
    #                          'gpiuezjw.data','tihzkoyu.data',
    #                          'hbctmwqj.data','ycqzmbrw.data',
    #                          'fkjhepcs.data','kczwtlrd.data',
    #                          'dwelszrk.data','uilqywot.data',
    #                          'xufnmacj.data','jrbiznkl.data',
    #                          'mrxtfkzj.data',f], "%s.png" % f)

最后逐个数据块测试 HEADER + IHDR + IDAT1 [+IDAT2...],详细exp.py,一个一个测试可以看到已经拼出得图像,如下图所示,名称为yvxmeawg.data,在第一张的基础上往后去试第二张,以此类推:
图3 第一张
最后复原完成的效果如下图所示:
图4 最终版

Happy_puzzle

Happy_puzzle

总结解题过程:
手撕PNG,提示里的RGB没管,400*400比较有用,
用windows比较方便的是,crc不用算,用0占位即可,IEND也可以不用加
最基本的PNG组成:文件头,IHDR,IDAT(len(data)+’IDAT’+data+crc),IEND,和随处可见的crc32校验(这玩意儿坑惨我了)
随便找个PNG,拿到png文件头+IHDR的数据
改宽高
给所有data文件,前面接上len(data),即00002800,IDAT,再给末尾加上00000000占crc32的位
做出26张图,看哪张图有图像,然后以此类推的再往后加data

温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-4-27 02:36 , Processed in 0.100743 second(s), 39 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表