misc24
题目提示:flag在图片上面
使用010editor打开图片,修改图片的高度第23个字节:96,换算成10进制是150,稍微改高一点改成250即:fa,保存后得到flag
至此得到本题flag:ctfshow{dd7d8bc9e5e873eb7da3fa51d92ca4b7}
misc25
题目提示flag在图片下面
应该还是更改图片高度,使用010editor打开图片,图片高度为96,转换成10进制是150,稍微改高一点改成250即:fa,保存后看到flag
至此得到本题flag:ctfshow{494f611cc5842dd597f460874ce38f57}
misc26
题目提示:flag还是在图片下面,但到底有多下面
还是修改图片高度,使用010editor打开图片,图片高度为96,转换成10进制是150,尝试将高度改成500即01 f4,发现出现了一半的flag
再改高一点,改成700即02 bc得到完整flag
至此得到本题flag:ctfshow{94aef125e087a7ccf2e28e742efd704c}
misc27
题目提示flag在图片下面
jpg图片改高度,先搜索FF C0往后数第四个字节和第五字节是图片的高,将高改成250即FA,保存后打开图片看到flag
至此得到本题flag:ctfshow{5cc4f19eb01705b99bf41492430a1a14}
misc28
题目提示flag在图片下面
gif图片从文件头开始数第七和第八个字节是宽,第九第十个字节是高,将高的值修改为250即FA,gif有多个地方要修改高度,可以直接搜索变量名称:height,发现一共有两个地方,修改保存后打开图片看到flag
至此得到本题flag:ctfshow{59c8bc525426166b1c893fe12a387fd7}
misc29
题目提示flag在图片下面
使用010editor打开,搜索变量名称height发现有11处高要修改,全部改成250即:FA
保存后使用Stegsolve打开图片,在第八帧发现flag
至此得到本题flag:ctfshow{03ce5be6d60a4b3c7465ab9410801440}
misc30
题目提示:正确的宽度是950
使用010editor打开bmp文件,第二行第三到第六个字节是宽,将其宽度改成950即03b6,修改时高度的16进制值要从右往左写,如高度是07 a1 20,写作20 a1 07,保存后查看得到flag
至此得到本题flag:ctfshow{6db8536da312f6aeb42da2f45b5f213c}
misc31
题目提示:要改成正确的宽度
使用010editor查看图像得知整个图像大小487256字节,图像的每个像素点由3个字节表示,文件头占 54个字节,正确的宽度应为 (总字节数-54)÷ 3 ÷高度= 宽度(结果取整)
(487256-54)÷3÷150=1082,将宽度修改成1082,保存后打开得到flag
至此得到本题flag:ctfshow{fb09dcc9005fe3feeefb73646b55efd5}
misc32
题目提示:要改成正确的宽
使用脚本通过正确的crc爆破png图片宽高,运行结果为:1044 150;hex: 0x414 0x96使用010editor修改图片正确高度,保存图片后得到flag
#通过正确的crc爆破png图片宽高
import binascii
import struct
crcbp = open("flag.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进行枚举
import binascii
import struct
crcbp = open("flag.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)
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)
至此得到本题flag:ctfshow{685082227bcf70d17d1b39a5c1195aa9}
misc33
题目提示:高度和宽度都改了
还是使用上一题的脚本,运行结果为:978 142;hex: 0x3d2 0x8e,使用010editor修改图片宽高,保存图片后得到flag
至此得到本题flag:ctfshow{03070a10ec3a3282ba1e352f4e07b0a9}
misc34
题目提示:IHDR块的CRC也改了,正确宽度肯定大于900
使用脚本爆破出正确的宽度,在1123得到flag
#每爆破一个就保存在脚本所在路径下
import zlib
import struct
filename = "flag.png" #修改成图片名字
with open(filename, 'rb') as f:
all_b = f.read()
#w = all_b[16:20]
#h = all_b[20:24]
for i in range(901,1200):#这里修改爆破宽的范围
name = str(i) + ".png"
f1 = open(name,"wb")
im = all_b[:16]+struct.pack('>i',i)+all_b[20:]
f1.write(im)
f1.close()
至此得到本题flag:ctfshow{03e102077e3e5de9dd9c04aba16ef014}
misc35
题目提示,出题人负隅顽抗,但正确宽度肯定大于900
将上一题的脚本改一下,尝试了一遍发现爆破出来的图片都打不开,想到可能要把高度改大一点,改成600即02 58
再次打开图片发现在图片下方发现一段类似flag的东西,再次使用脚本爆破,发现再宽为993-1000时得到flag
#jpg爆破宽
import zlib
import struct
filename = "flag.jpg"
with open(filename, 'rb') as f:
all_b = f.read()
#width = all_b[159:161]
#hight = all_b[157:159]
for i in range(901, 1200):
name = str(i) + ".jpg"
f1 = open(name, "wb")
im = all_b[:159]+struct.pack('>h', i)+all_b[161:]
f1.write(im)
f1.close()
至此得到本题flag:ctfshow{ca35201ca9ed607e5a68f44ef573fbc3}
misc36
题目提示:正确的宽度在920-950之间
使用010editor打开图片搜索变量名称width,发现一共有两处需要修改,将高度改高一点大概400就行,已经明确提示了宽度再920-950之间,使用二分法尝试修改发现宽度是941
至此得到本题flag:ctfshow{1ebf739f832906d60f57436b8179166f}
misc37
打开图片发现是一张动图,使用stegsolve中FrameBrowser逐帧查看,分别在第9帧、第14帧、第21帧、第31帧、第34帧发现flag片段,逐帧一起即是flag
至此得到本题flag:ctfshow{2056782cd57b13261dcbbe3d6eecda17}
misc38
使用TweakPNG打开图片,发现很多fdAT chunk(帧数据块),所以这是一张apng图片,使用Honeyview打开图片,在 第9、17、36、40 帧中得到flag片段,拼在一起就是flag
至此得到本题flag:ctfshow{48b722b570c603ef58cc0b83bbf7680d}
misc39
使用工具stegsolve查看gif图片,一共有287帧,逐帧查看并没有flag,这题是gif时间间隔隐写,需要在kali下安装imagemagick 工具
apt-get install imagemagick
用命令提取每帧间隔时间:
identify -format "%T " misc39.gif > flag.txt
得到一个文本文件,打开发现是由37和36
写一个脚本,实现将36和37替换成0和1,因为以往的flag都是41个字符,将转换后的二进制每七个为一组(287/41 = 7),然后转换为字符得到flag
str='37 37 36 36 36 37 37 37 37 37 36 37 36 36 37 37 36 36 37 37 36 37 37 37 36 36 37 37 37 37 36 37 36 36 36 37 37 36 37 37 37 37 37 37 37 36 37 37 37 37 37 37 37 36 37 37 36 37 37 36 37 36 37 36 37 37 36 36 37 36 36 37 37 37 36 36 36 36 37 37 36 36 36 37 36 37 37 36 36 37 36 37 37 36 36 37 37 36 37 37 36 36 37 37 36 36 37 37 37 36 36 37 36 37 37 37 36 36 37 36 37 37 36 37 36 37 37 37 36 36 37 37 36 37 37 36 36 36 37 36 36 37 37 36 37 37 37 37 37 36 36 36 37 36 37 37 36 36 37 36 37 36 37 37 36 36 37 36 36 37 37 36 37 37 36 36 37 37 37 36 36 36 37 37 36 36 37 36 36 36 37 37 37 36 36 37 36 37 37 36 37 37 36 36 37 37 36 36 37 37 37 37 36 36 36 36 37 36 37 37 37 36 36 37 37 37 36 36 37 36 37 37 37 36 36 36 37 36 37 37 36 36 36 37 37 37 37 36 36 36 36 37 36 37 37 36 36 36 36 36 37 37 36 37 36 36 36 37 37 36 37 36 37 36 37 37 37 36 36 37 37 37 37 37 37 36 37 '
str1=''
flag=''
str1=str.replace("37","1").replace("36","0").replace(" ","")#替换成0和1
for i in range(41):#循环41次
flag += chr(int(str1[7*i:7*(i+1)],2))
#先对str1就行切片,从str1中每七个二进制数提取子串
#int()将二进制字符串转换为整数,第二个参数2表示输入的字符串是二进制数字、
#chr()接受一个整数为参数,并返回整数对应的unicode字符
print(flag)
至此得到本题flag:ctfshow{52812ff995fb7be268d963a9ebca0459}
misc40
使用ApngDisassembler打开apng图片,inupt处选择apng文件,output处是输出文件的前缀,点击convert转换,会逐帧分离apng图片,并生成一个txt问问文件,里面是每张图片的delay
使用脚本将每个 txt 文本中=和/之间的字符开始提取出来转换成ascii码
flag=''
for i in range(1,69):
file= open('apngframe'+str(i).zfill(2)+'.txt')
#打开名为apngframe加上当前循环数字,再加上.txt的文件
#因为这个题的图片帧数是两位数,且生成出来的前9个文件名是01的形式,所以加了zfill()
j=file.read()
flag+=chr(int(j.split('/')[0].split('=')[1]))
#首先按/分割字符串,取第一部分(split('/')[0])
#然后再按=分割,取第二部分(split('=')[1])
#这样做的目的是提取出=右边的值
#将得到的字符串通过int()转换为整数,然后通过chr()转换为对应的ASCII字符
print(flag)
至此得到本题flag:ctfshow{95ca0297dff0f6b1bdaca394a6fcb95b}
misc42
使用Tweakpng打开图片,发现IDAT数据块的长度很像ascii码,使用脚本或在线工具转一下
str="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"
str1=str.split(',')
flag=""
for i in range(0,len(str1)):
flag+=chr(int(str1[i]))
print(flag)
至此得到本题flag:ctfshow{078cbd0f9c8d3f2158e70529f8913c65}
misc43
使用TweakPNG打开图片发现有很多crc报错,提取这些错误的crc,转换成字符串就是flag
方法一:
使用TweakPNG打开时会报错显示错误的crc,可以直接写下来,然后转字符串
方法二:
使用pngdebugger工具,可读取 PNG 图片的数据,检测每个数据块中的 CRC 是否正确
使用方法:
在安装目录下用cmd打开执行命令:
pngdebugger [png图片路径]
将错误的crc按顺序记录下来
至此得到本题flag:ctfshow{6eb2589ffff5e390fe6b87504dbc0892}
misc44
使用TweakPNG打开图片发现有很多crc报错,直接抄下来不太现实,使用pngdebugger,直接导成文本查看
pngdebugger misc44.png > crc.txt
发现正确和错误的数据块都很多,应该是二进制转换,写个脚本以实现读取文本内容,按照空格分隔字符串,每当读到一个OK!就追加一个1,每遇到一个FAILED就追加一个0,然后每八个一组转换成字符串,但是会发现最后生成的是一堆乱码
flag=""
file = open("crc.txt","r")#读取指定文本文件的所有内容
str=file.read()
file.close()
for i in str.split():
#将字符串按照空格分割成多个部分,并返回一个包含这些部分的列表
# print(i)
if i == "OK!":
flag += "1"
if i == "FAILED":
flag += "0"
#这是crc正确为1不正确为0的情况
print(flag)
print(len(flag)//8)
for i in range(43):
print(chr(int(flag[8*i:8*(i+1)],2)),end="")
继续查看文本内容,发现很多数据块都有1152这个数字,只有首尾的数据块没有,把其他没有1152的开头和结尾删除再使用脚本转换,结尾处1105的数据块保不保留都可以
删除后再次运行得到flag
至此得到本题flag:ctfshow{cc1af32bf96308fc1263231be783f69e}
misc45
题目提示:有时候也需要换一换思维格式
图片常见格式有png,jpg,gif, bmp,尝试将题目给的png图片转换成bmp文件,可以通过在线网站进行转换
网站链接:https://cdkm.com/cn/png-to-bmp
转换后使用binwalk查看bmp文件
分离出来一个gz压缩包,解压缩后得到flag图片
至此得到本题flag:ctfshow{057a722a5587979c34966c2436283e70}
未完待续······