此系列为Misc入门图片篇,不定期更新;
目的是介绍 Misc 方向中与图片相关的常见出题点;
题目按照知识点分类,并尽量保证难度为入门水平;
大部分题目仅涉及单一知识点,但可能有多种解法;
找到flag并不困难,关键是了解每一题背后的原理;
藏在哪?为什么可以这样藏?请多考虑这两个问题;
才疏学浅,人菜手残,若有错漏之处,还望指出;
希望能对刚接触 Misc 方向的朋友有所帮助。
图片篇(基础操作)
misc1
图片即是flag:ctfshow{22f1fb91fc4169f1c9411ce632a0ed8d}
misc2
010打开发现是张png图片,于是改后缀为png即可获取flag:ctfshow{6f66202f21ad22a2a19520cdd3f69e7b}
misc3
醉了呀!bpg这都是什么远古图片呀~
全网就一个软件能打开它(bpgviewer;
打开即可获得flag:ctfshow{aade771916df7cde3009c0e631f9910d}
附上附件(提取码:lk1b)
misc4
拼接起来就是flag:ctfshow{4314e2b15ad9a960e7d9d8fc2ff902da}
图片篇(信息附加)
misc5
010打开划到底部发现flag:ctfshow{2a476b4011805f1a8e4b906c8f84083e}
misc6
010打开直接搜ctfshow就能得到flag:ctfshow{d5e937aefb091d38e70d927b80e1e2ea}
misc7
flag在图片文件信息中。
直接换成txt打开Ctrl+F5搜ctfshow得到flag:ctfshow{c5e77c9c289275e3f307362e1ed86bb7}
misc8
flag在图片文件中图片文件中。
直接binwalk、foremost得到flag:ctfshow{1df0a9a3f709a2605803664b55783687}
misc9
flag在图片块里。
图片块==数据块;又是直接010打开搜ctfshow就能得到flag:ctfshow{5c5e819508a3ab1fd823f11e83e93c75}
misc10
flag在图片数据里。
010打开检测发现有个短的idat块有异常
接着就是直接用idat组合成另一张图片,使用zlib进行压缩,跑下脚本得到如下信息:
63746673686f777b33353332353234323461633639636236346636343337363838353161633739307d
附上脚本
import zlib
import binascii
IDAT = "789C4B2E492BCEC82FAF363635363235323132494C36B34C4E3233493333313637B3B030354C4C36B734A8050009960BD1".decode('hex')
result = binascii.hexlify(zlib.decompress(IDAT))
print(result)
16进制转一下即可得到flag:ctfshow{353252424ac69cb64f643768851ac790}
misc11
flag在另一张图里。
删掉第一个idat即可得到flag:ctfshow{44620176948fa759d3eeafeac99f1ce9}
misc12
flag在另一张图里。
同上,不过这里得把前八个idat块都删掉保存就能得到flag:ctfshow{10ea26425dd4708f7da7a13c8e256a73}
misc13
flag位置在图片末尾。
010打开按提示划到底部发现了如下疑似flag的信息
复制粘贴出16进制文本跑下脚本得到:
s="631A74B96685738668AA6F4B77B07B216114655336A5655434343678632534DD38EF66AB37103395391F628237BA6545627C3254647E313A64E465F136FA65F5341E3107321D665438F1333239E9616C7D"
flag=""
for i in range(0,len(s),4):
flag += s[i]
flag += s[i+1]
print(flag)
#63746673686F777B61653665343663343866373339623765623264316465366534313266383339617D
16进制转下得到flag:ctfshow{ae6e3ea48f518b7e42d7de6f412f839a}
misc14
flag在那张图里。
010打开发现有张图片
于是新建一个将其复制粘贴保存得到flag:ctfshow{ce520f767fc465b0787cdb936363e694}
misc15
flag被跳过去了。
010打开就看到了flag:ctfshow{fbe7bb657397e6e0a6adea3e40265425}
misc16
flag在图片数据里。
binwalk分离一下即可得到flag:ctfshow{a7e32f131c011290a62476ae77190b52}
misc17
flag在图片数据里。
binwalk发现有个破损的包,接着zsteg发现了隐藏的数据,于是我们将其提取出来
最后binwalk分离得到flag:ctfshow{0fe61fc42e8bbe55b9257d251749ae45}
misc18
flag在标题、作者、照相机和镜头型号里。
根据提示在详细信息中找到并拼接得到flag:ctfshow{325d60c208f728ac17e5f02d4cf5a839}
misc19
flag在主机上的文档名里。
根据提示我百度找到了个在线工具查的图片信息进而得到flag:ctfshow{dfdcf08038cd446a5eb50782f8d3605d}
misc20
flag在评论里。
同上利用在线工具查到评论信息
谐音梗!!西替爱抚秀 = ctfshow!!所以flag是ctfshow{c97964b1aecf06e1d79c21ddad593e42}
misc21
flag在序号里。
同上找到和序号相关的信息
hex后发现hex(X&Ys);也就是还需要X分辨率、Y分辨率、X定位、Y定位
最后将那四组数据分别转成16进制拼接并套上ctfshow{}得到flag:ctfshow{e8a221498d5c073b4084eb51b1a1686d}
misc22
flag在图片里。
参考文章了解一下app0 app1(此位置允许保存一个原图的缩略图
010打开对照结构正常写在app那几个段得到flag:ctfshow{dbf7d3f84b0125e833dfd3o80820a129}
眼睛都要看瞎了but提交还是一直不对..
呜呜呜 ~ 真flag:ctfshow{dbf7d3f84b0125e833dfd3c80820a129}
对了,还有那个缩略图用stegsolve的full blue看会更清晰
misc23
flag在时间里。
盲搜一波ctf意外收获四个时间段(1997-09-22T02:17:02+08:00、2055-07-15T12:14:48+08:00、2038-05-05T16:50:45+08:00、1984-08-03 18:41:46+08:00)
接着分别将得到的四个时间转波时间戳得到如下信息
874865822
2699237688
2156662245
460377706
最后我们16进制转一下试试对(mei)不(mao)对(bing),得到flag:ctfshow{3425649ea0e31938808c0de51b70ce6a}
图片篇(文件结构)
misc24
flag在图片上面。
改高度得到flag:ctfshow{dd7d8bc9e5e873eb7da3fa51d92ca4b7}
PS:写个小技巧⑧,大家可以将图片的高宽转为16进制并搜索找到对应位置,然后将更改好的数据填进去保存即可
misc25
flag在图片下面。
同上,得到flag:ctfshow{494f611cc5842dd597f460874ce38f57}
misc26
flag还是在图片下面,但到底有多下面?。
再调高点就好了,其中图片高度还需要我们跑下脚本来爆破出得到flag:ctfshow{94aef125e087a7ccf2e28e742efd704c}
附上脚本
import binascii
import struct
crcbp = open("misc26.png", "rb").read()
for i in range(2000):
for j in range(2000):
data = crcbp[12:16] + struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
if(crc32 == 0xEC9CCBC6):
print(i, j)
print('hex:', hex(i), hex(j))
#0x25e
misc27
flag在图片下面。
同上(指misc24,得到flag:ctfshow{5cc4f19eb01705b99bf41492430a1a14}
misc28
flag在图片下面。
同上,得到flag:ctfshow{59c8bc525426166b1c893fe12a387fd7}
misc29
flag在图片下面。
同上,得到flag:ctfshow{03ce5be6d60a4b3c7465ab9410801440}
对了,gif我每一帧都把他高度给改了
misc30
正确的宽度是950。
根据提示将高度改为950即可得到flag:ctfshow{6db8536da312f6aeb42da2f45b5f213c}
misc31
高度是正确的,但正确的宽度是多少呢。
还是第一次遇到bmp的这种题
参考文章:https://zhuanlan.zhihu.com/p/260702527
大概了解了下bmp的文件结构就开始做题辣~
首先我们从FF那开始一直复制到最后看看它的文件大小(最后那个不用管他,故意多加的⑧),然后用它除以三就是像素值,最后根据提示高度正确算出正确的宽度,也就是说487202/3/150=1082便是正确的那个宽度了
最后改下宽即可得到flag:ctfshow{fb09dcc9005fe3feeefb73646b55efd5}
misc32
高度是正确的,但正确的宽度是多少呢。
010打开查找图片的CRC:0xE14A4C0B
跑脚本爆破它的宽
附上脚本
import binascii
import struct
crcbp = open("misc32.png", "rb").read()
for i in range(2000):
for j in range(2000):
data = crcbp[12:16] + struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
if(crc32 == 0xE14A4C0B):
print(i, j)
print('hex:', hex(i), hex(j))
#1044 150
#hex: 0x414 0x96
最后改下宽即可得到flag:ctfshow{685082227bcf70d17d1b39a5c1195aa9}
misc33
出题人丧心病狂,把高度也改了
老样子,010打开找到图片的CRC:0x5255A798
跑脚本爆破它的高宽
附上脚本
import binascii
import struct
crcbp = open("misc33.png", "rb").read()
for i in range(2000):
for j in range(2000):
data = crcbp[12:16] + struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
if(crc32 == 0x5255A798):
print(i, j)
print('hex:', hex(i), hex(j))
#978 142
#hex: 0x3d2 0x8e
最后改下高宽即可得到flag:ctfshow{03070a10ec3a3282ba1e352f4e07b0a9}
misc34
出题人狗急跳墙,把IHDR块的CRC也改了,但我们知道正确宽度肯定大于900
由于crc都给改了,我们只能通过爆破获取flag惹,在一堆黑图中看到了张含有flag的图:ctfshow{03e102077e3e5de9dd9c04aba16ef014}
附上脚本
import struct
import zlib
f = open(r'misc34.png','rb')
c = f.read()
width = c[16:20]
height = c[20:24]
for i in range(900,1200):
f1 = open('./out/'+str(i)+'.png','wb')
img = c[:16]+struct.pack('>i',i)+c[20:]
f1.write(img)
f1.close()
misc35
出题人负隅顽抗,但我们知道正确宽度肯定大于900
这里我们先把高度改高一些到能看到下面的东西(这里我把高改到1000),然后同上跑脚本得到flag:ctfshow{ca35201ca9ed607e5a68f44ef573fbc3}
附上脚本
import struct
import zlib
f = open('misc35.jpg','rb')
c = f.read()
for i in range(900,1000):
f1 = open('./out/'+str(i)+'.jpg','wb')
img = c[:c.index(b'\x03\xe8\x03\x84')+2]+struct.pack('>h',i)+c[c.index(b'\x03\xe8\x03\x84')+4:]
f1.write(img)
f1.close()
misc36
出题人坦白从宽,正确的宽度在920-950之间
gif这个给我坑了好长时间~ 其实和前面还是一个样跑脚本得到flag:ctfshow{1ebf739f832906d60f57436b8179166f}
不说了直接看脚本吧~ 呜呜呜~
import struct
import zlib
f = open('misc36.gif','rb')
c = f.read()
for i in range(900,950):
f1 = open('./out/'+str(i)+'.gif','wb')
img = c[:c.index(b'\x00\x00\x84\x03\xb6\x03')+2]+struct.pack('>h',i)[::-1]+c[c.index(b'\x00\x00\x84\x03\xb6\x03')+4:]
f1.write(img)
f1.close()
misc37
flag在图片里
逐帧保存翻看即可得到flag:ctfshow{2056782cd57b13261dcbbe3d6eecda17}
misc38
flag在图片里
奇怪的知识增加.jpg 见识到了什么叫apng(想了解更多就自行百度~
这里我直接利用其 专门的工具(提取码:2v42)打开得到flag:ctfshow{48b722b570c603ef58cc0b83bbf7680d}
misc39
flag就像水,忽快忽慢地流
gif帧数间隔隐写,使用工具 ImageMagick(提取码:t7hc)提取帧数
这里友情提醒千万别用Windows下的各种版本都bug无数,亲测!!因此我发的也是Linux下的~ 不信你就自己爬去官网下一个试试(或者去更好用的中文站:http://www.imagemagick.com.cn/download.html)
kali下编译安装
./configure
make
make install
kali下提取帧数
identify -format "%T " misc39.gif > misc39.txt
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
转01再七位一组转字符即可得到flag:ctfshow{52812ff995fb7be268d963a9ebca0459}
附上脚本(白嫖V3geD4g师傅脚本.jpg)
s = '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'
s = s.replace('37','1').replace('36','0').replace(' ','')
# s = s[1:]
print(s)
print(len(s))
for i in range(len(s)//7):
try:
print(chr(int(s[i*7:i*7+7],2)),end='')
except:
pass
#11000111110100110011011100111101000110111111101111111011011010101100100111000011000101100101100110110011001110010111001011010111001101100010011011111000101100101011001001101100111000110010001110010110110011001111000010111001110010111000101100011110000101100000110100011010101110011111101
#287
#ctfshow{52812ff995fb7be268d963a9ebca0459}
misc40
flag就像歌,有长有短仿佛岁月悠悠
原理同上,只是换成apng的帧时间间隔隐写(也就是misc38的操作对其进行分解),最后跑下脚本得到flag:ctfshow{95ca0297dff0f6b1bdaca394a6fcb95b}
附上脚本(V3geD4g TQL!)
for i in range(28,69):
f = open('./misc40/apngframe'+str(i)+'.txt')
c =f.read()
print(chr(int(c.split('/')[0].split('=')[1])),end='')
misc41
(本题为Misc入门图片篇和愚人节比赛特别联动题)
H4ppy Apr1l F001's D4y!
愚人节到了,一群笨蛋往南飞,一会儿排成S字,一会儿排成B字。
根据提示搜索下f001就直接看到了flag:ctfshow{fcbd427caf4a52f1147ab44346cd1cdd}
misc42
flag有多长?2cm……不好意思打错了,41位
IDAT块长度隐写,借助工具tweakpng(010也行),跑下脚本得到flag:ctfshow{078cbd0f9c8d3f2158e70529f8913c65}
贴上脚本:
s = [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='')
#ctfshow{078cbd0f9c8d3f2158e70529f8913c65}
misc43
错误中隐藏着通往正确答案的道路
crc隐写,010打开将各个idat的crc提取出来得到flag:ctfshow{6eb2589ffff5e390fe6b87504dbc0892}
misc44
错误中还隐藏着坑
利用一款自动化检测修复PNG损坏的取证工具PCRT进行修复crc校验出错
我是kali下整的
git clone https://github.com/sherlly/PCRT.git
cd PCRT
python PCRT.py -y -v -i misc44.png > 44.txt
再跑下脚本得到flag:ctfshow{cc1af32bf96308fc1263231be783f69e}
f = open('44.txt')
res = ''
while 1:
c = f.readline()
if c:
if 'chunk crc' in c:
# print(c)
res+='0'
elif 'Correct IDAT CRC' in c:
res+='1'
else:
break
print(res)
print(len(res))
for i in range(len(res)//8):
a = res[i*8:i*8+8]
try:
print(chr(int(a,2)),end='')
except:
pass
#11111111111111110110001101110100011001100111001101101000011011110111011101111011011000110110001100110001011000010110011000110011001100100110001001100110001110010011011000110011001100000011100001100110011000110011000100110010001101100011001100110010001100110011000101100010011001010011011100111000001100110110011000110110001110010110010101111101
#344
#ÿÿctfshow{cc1af32bf96308fc1263231be783f69e}
misc45
有时候也需要换一换思维格式
不做了不做了(手动滑稽
misc46
你见过扶乩吗
利用工具 ImageMagick 得到每帧的偏移量,然后将它作为坐标来画图,写个脚本跑一下即可得到flag:ctfshow{05906b3be8742a13a93898186bc5802f}
附上脚本
from PIL import Image
import matplotlib.pyplot as plt
f = open('46.txt')
pp = []
while 1:
c = f.readline()
if c:
s = eval(c.split('+')[1]+','+c.split('+')[2][:2])
pp.append(s)
print(s)
# print(c)
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)
plt.imshow(img)
plt.show()
misc47
没见过扶乩,那你知道笔仙吗
原理同上,只是这里换成了apng,跑下脚本得到flag:ctfshow{6d51f85b45a0061754a2776a32cf26c4}
附上脚本
import struct
from PIL import Image
import matplotlib.pyplot as plt
f = open('misc47.png','rb')
c = f.read()
c = c[c.index(bytes.fromhex('6663544C00000001')):]
pp = []
for i in range(1,1124,2):
start = c.index(bytes.fromhex('6663544C0000')+struct.pack('>h',i))
# start = c.index(bytes.fromhex('6663544C000000'+hex(i)[2:]))
# print(start)
fc = c[start:start+30]
print(fc[18:20],fc[22:24])
print(struct.unpack('>h',fc[18:20])+struct.unpack('>h',fc[22:24]))
pp.append(struct.unpack('>h',fc[18:20])+struct.unpack('>h',fc[22:24]))
# print(fc.index(b'\xb6'),fc.index(b'\x34'))
# print(c[:100])
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)
plt.imshow(img)
plt.show()
misc48
附件的第(Di)七(Qi)题(Ti)中有提示。本题略脑洞,可跳过
不做了不做了(手动滑稽
misc49
它们一来就是十六种。本题略脑洞,可跳过
不做了不做了(手动滑稽
图片篇(颜色通道)
misc50
有时候视线也要放低一点
steg打开在红绿蓝三个通道中找到flag:ctfshow{84470883ee1eec2e886436461bf79111}
0 条评论