杂项入门-图片篇(文件结构)

misc 24

hint:flag在图片上面

所以这道题应该是要修改图片的高度。

直接 010 打开,修改 0010h 行 6 列的 96 为 FF 然后再打开图片即可。

计算一下:

文件头字节: 53

文件尾:675053 (最后的 00 00 不算,是 windows 补充的,算到 FF 结尾即可)

总字节数 = (675053 - 53) = 675000

因为一个像素点由 RGB 三个通道组成,一个通道一个字节。

所以原有的像素值 = 675000 / 3 = 225000 px

我们右键图片查看属性:像素点 = 900*150 < 225000

本着宽度不变,高度应该 = 225000 / 900 = 250 px

misc 25

hint:flag在图片下面。

一样的把图片拉高即可

misc 26

用 Tweakpng 打开图片(010 运行模板也可校验)

在这里插入图片描述

crc 校验不对,一定是图片宽高,修改高度一看,要求求出原有高度,上脚本

import binascii
import struct

crcbp = open("D:\desktop_in_D\题目附件垃圾桶\misc26.png", "rb").read()  # 打开图片
crc32frombp = int(crcbp[29:33].hex(), 16)  # 读取图片中的CRC校验值
print(crc32frombp)

for i in range(4000):  # 宽度1-4000进行枚举
    for j in range(4000):  # 高度1-4000进行枚举
        data = crcbp[12:16] + \
               struct.pack('>i', i) + struct.pack('>i', j) + crcbp[24:29]
        crc32 = binascii.crc32(data) & 0xffffffff
        # print(crc32)
        if (crc32 == crc32frombp):  # 计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
            print(i, j)
            print('hex:', hex(i), hex(j))
            exit(0)

misc 27

hint:flag在图片下面

010 打开图片,alt + 4 打开模板,找到宽高位置改高度即可

在这里插入图片描述

misc 28

继续修改高度,但是得预览或者 Stegsolve 打开才能看到图片

misc 29

题目提示还是让我们改高度。

打开来是 gif 文件。所以要一帧一帧改高度,然后丢到 Stegsolve 的 Analyse 的 Frame Browser 模块一帧一帧看

misc 30

正如题目提示修改宽度为 950 即可

misc 31

高度正确让我们计算宽度。

(487253-53)/ 3 / 150 = 1082.666666666667

所以宽度改为 1082

misc 32

高度正确计算宽度,因为是 png 所以脚本爆破即可

misc 33

依然爆破

misc 34

hint:出题人狗急跳墙,把IHDR块的CRC也改了,但我们知道正确宽度肯定大于900

文件头的 crc 值被修改,所以 crc 校验已经能通过了(虽然修改了文件宽度)

所以上面的靠 crc 爆破宽高脚本失效。

那我们就直接爆破宽度然后另存为图片看一下哪一张能正常显示

import zlib
import struct
filename = r"D:\desktop_in_D\题目附件垃圾桶\misc34.png"
with open(filename, 'rb') as f:
    all_b = f.read()
    for i in range(901,1200):
        name = str(i) + ".png"
        f1 = open(r"D:\desktop_in_D\题目附件垃圾桶\\" + name,"wb")
        im = all_b[:16]+struct.pack('>i',i)+all_b[20:]
        f1.write(im)
        f1.close()

在这里插入图片描述

脚本一把梭哈

在这里插入图片描述

misc 35

hint:出题人负隅顽抗,但我们知道正确宽度肯定大于900

import zlib
import struct
filename = r"D:\desktop_in_D\题目附件垃圾桶\misc35.jpg"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[159:161]
    #h = all_b[157:159]
    for i in range(901,1200):
        name = str(i) + ".jpg"
        f1 = open(r"D:\desktop_in_D\题目附件垃圾桶\\" + name,"wb")
        im = all_b[:159]+struct.pack('>h',i)+all_b[161:] # jpg 宽度长度区域两个字节,所以用 >h
        f1.write(im)
        f1.close()

爆破 jpg 图片的宽度,还要把高度拉高一点看得到,宽度爆破出来是 997

misc 36

hint:出题人坦白从宽,正确的宽度在920-950之间

可以一个一个试,或者上脚本

import zlib
import struct
filename = r"D:\desktop_in_D\题目附件垃圾桶\misc36.gif"
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[159:161]
    #h = all_b[157:159]
    for i in range(920,951):
        name = str(i) + ".gif"
        f1 = open(r"D:\desktop_in_D\题目附件垃圾桶\\" + name,"wb")
        im = all_b[:38]+struct.pack('>h',i)[::-1]+all_b[40:] # gif 宽度长度区域两个字节,所以用 >h
        f1.write(im)
        f1.close()

misc 37

stegsolve 一帧一帧看即可

misc 38

binwalk 分离一下然后拖到 TweakPng 里面打开,可以发现是 APNG,是 png 的扩展,动图。

在这里插入图片描述

所以我们也拖到 stegsolve 里面,但是不行啊,看来这个只能看 gif 图片。

不过我们有了认识了一个新工具,honeyview 。

在第 9,14,21,31,34 帧上面。

ctfshow{2056782cd57b13261dcbbe3d6eecda17}

misc 39

hint:flag就像水,忽快忽慢地流

打开来是一个动图。有 287 帧,一开始看提示我还以为是出题人调节了动图的速度,人眼看不出来,但是一帧一帧看还是没找到。

其实是动图的每一帧间隔时间不同传递信息

下载工具

apt-get install imagemagick

执行命令将每帧的间隔时间导出到 1.txt

identify -format "%T" misc39.gif > 1.txt

打开来发现由一堆 36,37组成。

把 37 转为 1,36 转为 0,然后 flag 41个字符 287 / 41 = 7,所以把 01 字符串分为 41 组,一组 7 个字符,转 ascii ;

str = '3737363636373737373736373636373736363737363737373636373737373637363636373736373737373737373637373737373737363737363737363736373637373636373636373737363636363737363636373637373636373637373636373736373736363737363637373736363736373737363637363737363736373737363637373637373636363736363737363737373737363636373637373636373637363737363637363637373637373636373737363636373736363736363637373736363736373736373736363737363637373737363636363736373737363637373736363736373737363636373637373636363737373736363636373637373636363636373736373636363737363736373637373736363737373737373637'

# 37  替换为1,36替换为0
str = str.replace('37','1')
str = str.replace('36','0')
print(str)
# # 七个字符为一组转化为 ascii 字符
str = [chr(int(str[i:i+7],2)) for i in range(0,len(str),7)]

print(''.join(str))

misc 40

hint:flag就像歌,有长有短仿佛岁月悠悠

APNG 格式的动图,有一帧一帧看不到 flag,binwalk 分离不了 apng。用 APNG Disassembler 分离。

在这里插入图片描述

得到一堆 txt,看来是在每一帧图片之间隐藏信息。

打开 txt,都是类似这种格式

在这里插入图片描述

用脚本把每个 txt 的 229 位置上的数提取转 ascii 字符

flag=""
for i in range(1,69):
    if(i<10):
        f = open('D:\desktop_in_D\题目附件垃圾桶/apngframe0'+str(i)+'.txt')
    else:
        f = open('D:\desktop_in_D\题目附件垃圾桶/apngframe'+str(i)+'.txt')
    s = f.read()
    flag += chr(int(s.split("/")[0][6:]))
print(flag)

得到 flag

ctfshow{95ca0297dff0f6b1bdaca394a6fcb95b}

misc 42

hint:flag有多长?2cm……不好意思打错了,41位

010 打开发现有很多长短不一的 IDAT 块。

用 TweakPng 打开,发现 idat 长度不一

在这里插入图片描述

把长度转为 ascii字符即可

s = [229,152,191,229,152,191,49,99,116,102,115,104,111,119,123,48,55,56,99,98,100,48,102,57,99,56,100,51,102,50,49,53,56,101,55,48,53,50,57,102,56,57,49,51,99,54,53,125]
for i in s:
    print(chr(i),end='')

misc 43

hint:错误中隐藏着通往正确答案的道路

我直接 010 打开就找到了,它给我标紫色了。。。。应该非预期了。

010 打开又是一大堆 IDAT, 拖到 TweakPNG 里面直接报错

在这里插入图片描述

结合 hint should 前面的字符串应该就和 flag 有关,都收集起来然后 16 进制转字符串即可

misc 44

hint:错误中还隐藏着坑

010 打开 又看到很多 IDAT 块,这次太多了,按照上一步的做法不太现实。

用一个新工具 pngDebugger,作用官方解释是 Read PNG headers, Check CRC

把检测结果导出到 txt 里

PNGDebugger D:\desktop_in_D\题目附件垃圾桶\misc44.png  > 1.txt

在这里插入图片描述

把 CRC 校验结果 OK 计为 1 , FAILED 记作 0,统计联合起来转为 ascii。

# 二进制转换为字符串 8 位一组
def bin2str(bin_str):
    strs = ''
    for i in range(0, len(bin_str), 8):
        strs += chr(int(bin_str[i:i + 8], 2))
    return strs

strs=''
file_name=r'E:\tools\MISC\png-debugger-master\Debug\1.txt'
with open(file_name, "r") as f:
    lines = f.readlines()
    for line in lines:
        if "OK" in line:
            strs += '1'
        elif "FAILED" in line:
            strs += '0'
# strs 转为 ascii

print(bin2str(strs))

但是这样不行啊,统计了一下 01 长度,发现是 346,不能整除 8 就很难受。再看一下题目应该是只要我们统计 IDAT 的校验,所以先把文本中前十行和最后4行 IHDR 和 IEND 的无用数据去掉,这样就变成 344 个 01 了。刚好够整除 8,8位一组转 ascii 码,用我上面那个脚本

在这里插入图片描述

misc 45

hint:有时候也需要换一换思维格式

png和bmp像素点的读取方式不一样,结合提示 思维格式,我们把 png 转化为 bmp (感觉题解太扯淡了)

然后 binwalk -e 分离得到 flag.png

misc 46

hint:你见过扶乩吗

用 identify xxx .gif > 1.txt 得到 gif 每一帧信息。

然后提取出每一帧 xy 轴偏移量,最后利用偏移量绘图

在这里插入图片描述

from PIL import Image
import matplotlib.pyplot as plt
f=open('D:\desktop_in_D\题目附件垃圾桶\q.txt')
pp=[]
while 1:
    c=f.readline()
    if c:
        s=eval(c.split('+')[1]+','+c.split('+')[2][:2])
        pp.append(s)
        print(s)
    else:
        break
img =Image.new('RGB',(400,70),(255,255,255))
for i in pp:
    new = Image.new('RGB',(1,1),(0,0,0))
    img.paste(new,i)
img.save('1.png')

misc 47

下载附件为一张 png 图片,是 APNG,也有偏移量。

010打开,有 fcTL 块,是帧控制块, 属于 PNG 规范中的辅助块,包含了当前帧的序列号、图像的宽高及水平垂直偏移量,帧播放时长和绘制方式(dispose_op 和 blend_op)等,每一帧都有一个 fcTL 块。

所以需要从十六进制中提取出偏移量的坐标,再通过坐标进行绘图。

misc 48

在这里插入图片描述

让我们计算 FF 数量,算 32 组刚好就是 flag

计算每两个有意义块之间的FF的数量再减一,因为这段中的最后一个FF是下一个有意义块的开头,所以这个 最后一个 FF 是特例,不用计算

0 12 11 0 7 10 13 13 9 0 9 13 0 13 6 0 10 9 2 1 0 1 10 8 11 5 12 7 2 2 3 10

再 10 进制转为 16 进制

arr = [0,12 ,11 ,0 ,7, 10 ,13 ,13, 9 ,0 ,9 ,13 ,0, 13 ,6 ,0 ,10 ,9 ,2, 1 ,0 ,1, 10 ,8 ,11, 5 ,12 ,7 ,2 ,2 ,3 ,10]
for i in arr:
    print(hex(i)[2:],end='')

得到

0cb07add909d0d60a92101a8b5c7223a

组合一下

ctfshow{0cb07add909d0d60a92101a8b5c7223a}

misc 49

hint:它们一来就是十六种。本题略脑洞,可跳过

查看 FF E0 - FF EF,16种,刚好32个,E 后面那位就是 flag 里的内容

在这里插入图片描述

全部组合起来就是 flag :0c618671a153f5da3948fdb2a2238e44

ctfshow{0c618671a153f5da3948fdb2a2238e44}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值