游戏秘籍
题目名称:游戏秘籍
题目说明:做为程序员我的,竟然无法调出30条命,我用笔记记录下来了。
0x01 LSB隐写
下载后是一张魂斗罗的图片30.png
,先用zsteg 30.png
查看一下,发现有PK开头的字符,可能是压缩包,用zsteg -E "extradata:0" 30.png > 30.zip
提取压缩包。
0x02 压缩包重组
用010editor
打开,发现一段提示:Need_Find_The_Passwd_to_unzip_file0
,保存压缩包后,双击打开发现压缩包损坏,而且开头是50 4B 01 02
。
打开一个正常压缩包会发现开头是50 4B 03 04
,而且在结尾处会有50 4B 01 02
和50 4B 05 06
等字段,怀疑需要将压缩包重组,搜索05 06、03 04
字段,发现均缺少50 4B
,加上后重组顺序。压缩包可以正常打开,但需要密码。
0x03 IDAT数据隐写
目标转到原图30.png
,对图像尝试各种隐写无果,用010editor
打开,发现存在很多*ERROR: CRC Mismatch @ chunk[17]; in data: 5468655f; expected: 4a57f189
类似的错误。
将in data:
后的数据拷贝出来,按照顺序生成二进制文件,得到hint:The_hint_is:U1kkgG:VbDE3[1oy[1Ee
DEy0ghSzF>>>>上面字符串异或零叉零三然后在BASE64解码。You_
写python脚本获得密码What?That_is_a_passwd?!
解压压缩包得到Flag.txt
,到这一步感觉已经胜利在望了,没想到才刚刚开始= = 。
import base64
str1 = "U1kkgG:VbDE3[1oy[1Ee`DEy`0ghSzF>>>>"
flag_base64=""
for i in range(len(str1)):
a = ord(str1[i])^0x03
flag_base64 += chr(a)
print(flag_base64)
flag = base64.b64decode(flag_base64)
# What?That_is_a_passwd?!
0x04 LaTeX公式
打开txt文档发现是一串下面的编码,游戏笔记 \begin{array}{c}\begin{array}{c}\begin{array}{c|ccccc}\\\uparrow\uparrow&0&1&2&3&4\\\hline0&1&1&1&1&1
,查了很久资料发现是LaTeX
代码,官方给出Hint2:MD真好用,继续查资料发现在md语法中两个$$中可以加入LaTeX
代码,就会表示成公式。
0x05 二维码
看到了5行5列的表格,全是由01组成,想到了二维码,根据题目魂斗罗调30条命,百度发现秘籍是 上上下下左右左右BABA
,(这里也是一个小Bug,可能主办方没想那么多,我开始也没想那么多,就用上上下下左左右右ABAB
来排列的),具体代码如下:
from PIL import Image
from zlib import *
MAX = 23
pic = Image.new("RGB", (MAX, MAX))
str = "1111111000010110111111110000010011110101000001101110101101101010111011011101001101110101110110111010010000001011101100000100000101010000011111111011010010111111100000000110111100000000111011111110110110001001000001010000001111101111101001101001000100010101111111001000110101100111100000111100101110001000001110101000001010101111110011111111111010000000010101010001101111111110100101101010101100000101111111000100011011101010000111111010110111010000110011110110101110101110011111011011000001010110101100011111111110111001001100001"
i = 0
for y in range(0, MAX):
for x in range(0, MAX):
if(str[i] == '1'):
pic.putpixel([x, y], (0, 0, 0))
else:
pic.putpixel([x, y], (255, 255, 255))
i = i+1
pic.show()
pic.save("flag.png")
生成了一个23x23的二维码,但是怎么扫都不对,开始做题的时候也觉得23x23的尺寸不合理,但是想到已经到这一步了,可能不会再有坑了,没想到果然又是一个坑。
0x06 零宽字节隐写
其实在用Typora
打开LaTeX
代码的时候就发现了很多红点,最后5分钟,主办方又提示注意隐写才想到零宽字节隐写,加上想到version2 二维码的标准大小应该是25x25才恍然大悟,但时间已经来不及了。零宽字节隐写解密网站:https://330k.github.io/misc_tools/unicode_steganography.html
,注意不要全部复制,要单行解密。最终生成一个二维码扫描得到flagBMZCTF{y0u_f1nd_the_4l@g}
。
from PIL import Image
from zlib import *
MAX = 25
pic = Image.new("RGB", (MAX, MAX))
str = "1111111011001011101111111100000100011110010100000110111010111011001010111011011101001110101101011101101110100010000000101110110000010010001101010000011111111010101010101111111000000001110111110000000011101111101101010110001000001010110100010100010011100000101100000001111101111101001100100010001000101011111110001000011010110011110000001111100101110010100111000110110100100110100000111101011000001010101111110101111111111110100000000100101101000110111111111011001011101010101100000101111111110001000110111010110000111111101011011101000001100011110110101110101011001111110110110000010100110110110001111111111011110011001100001"
i = 0
for y in range(0, MAX):
for x in range(0, MAX):
if(str[i] == '1'):
pic.putpixel([x, y], (0, 0, 0))
else:
pic.putpixel([x, y], (255, 255, 255))
i = i+1
pic.show()
pic.save("flag.png")
总结:
感觉这道Misc题出的很好,师傅很用心了,听主办方说这题最终只有一解,还是在最后几分钟,感觉很可惜。但确实学到了很多东西,尤其是md添加LaTeX公式这种操作,还加深了对零款字节的理解。