# Mz1 的试炼之地
在 B 站发现了一个打 CTF 的 UP 猪,他搭建了一个 CTF 的练习靶场,自己就试玩一下,有兴趣的朋友可以自己去练练手
靶场地址:http://ctf.mz1.top/
# 娱乐小故事系列 1
# mission -1
第一题送分题,用 md5
加密 22642855
, 得到加密后的 hash
值,取前面 7 个字符
直接在 linux
下用 md5sum
命令获取 22642855
加密后的 hash
值,配合管道符和 cut
命令获取前面 7 个字符
echo 命令必须加上参数 -n 表示不换行输出才可以得到正确的 Hash 值,否则输出的则是错误的 Hash 值
# mission -2
第二题明显是一道编码题,下载该图片,通过 OCR 软件或者在线网站提取里面的字符,由于图片过于模糊,提取的字符可能不太正确,这个还需要自己更正
如果想练打字速度,也可以按照图片手动打出对应的字符
用 Base64
对其解码,得到解码后的明文
解密后的真相,是个悲伤的故事!!!
输入解码后的明文获取 Flag
# mission -3
第三题只给出一张图片,一般这种题目都是需要下载分析该图片,先把图片下载到本地,打开查看图片属性详情,看看能不能找到我们要的 Flag
很可惜,在属性里并没有我们要的信息,用 Stegsolve
打开图片,查看图片信息中是否隐藏了 Flag
非常幸运,在 File Format
里找到了我们想要的 Flag
# mission -4
第四题是一道选择题,选项只有 wealth、fame、power
三个,但是无论我们选择那个,都无法得到正确的 Flag
按 F12
打开浏览器开发者工具,按下快捷键 Ctrl + Shift + C
查看页面元素
在源代码中找到作者留下的提示 It is love, my boy.
, 很明显我们需要选择的答案是 love
,但是源代码中并没给我们 love
的选项,在这里我们可以直接在开发者工具中修改源代码的 wealth、fame、power
其中一个选项的 value
值为 love
或者新增一个 love
选项
提交后得到对应的 Flag
值
# mission -5
第五题进去后点击超链接跳转到题目页面,在题目页面只找到一串二进制的线索,并没有发现其它有价值的线索
把这串二进制复制到文本,在 linux
用 wc -c
统计字节个数
结果是 841 个字符,由于 wc
命令统计字节数会加上文本结尾的换行符,所以减去换行符后就是 840 个字符
先尝试把二进制转换成十六进制,再把十六进制转换成 ASCII码
,然后再从 ASCII码
看看有没有其它线索
用 Python 可以很简单的实现各进制之间的换行,转换成十六进制后我发现一个问题, ASCII码
的有效值是 0~127,十六进制转换 ASCII码
需要用两个十六进制数表示,而两个十六进制的数取值范围是 0~255,所以不能直接转,大于 127 的数转成 ASCII码
会出现乱码,这里就需要用 if
去判断,如果大于 127 则减去 128,保证其结果为有效的 ASCII码
str = hex(int('111001011010011010000010111001101001111010011100111001001011100010001010111001011010010010101001111010001000001110111101111001011010010010011111111001111011101110011001111001101000100010010001111001001011100010000000111001001011100010101010111001011000011010001101111001101001110110100101111001001011100010000000111001101010110010100001111001111001101010000100111001101001110010111010111001001011110010011010111011111011110010001100111001101000100010010001111001001011110010011010111001011010111110111001111010011000001010100011111001001011100010101010111001011010010110110011111001011010110110101001111001011010110110010000111010001010111110110100111001001011100010001001111001001011100010101010111001011010110110010111111011111011110010011010111001101000100010010001111001111000100010110001111001001011110110100000111000111000000010000010',2)) | |
flag = "" | |
for i in range(2,len(str),2): | |
if ((int(str[i] + str[i+1],16)) > 127): | |
flag += chr((int(str[i]+str[i+1],16)) - 128) | |
else: | |
flag += chr(int(str[i] + str[i+1])) | |
print (flag) |
结果依然是有乱码存在,但是感觉好像有点像 Flag
的意思,修改一下代码,把 99 以内不包含 a-f
的十六进制转换成十进制再转换成 ASCII码
看看
芜湖,被啪啪啪打脸
好吧,再回去看看线索,感觉这串二进制排列出来的形状有点像二维码,通过计算发现 29^2=841,而这串二进制则有 840 个字符,这会不会是巧合呢?
但是横竖 29 个像素也太小了,感觉并不怎么符合二维码的特征
不管了,马上百度一下 Python 如何将二进制转换成二维码,在前后补个 0
或 1
先看看能不能把这串二进制转换成有效二维码再说
from PIL import Image | |
MAX = 29 | |
pic = Image.new("RGB",(MAX,MAX)) | |
str ="111001011010011010000010111001101001111010011100111001001011100010001010111001011010010010101001111010001000001110111101111001011010010010011111111001111011101110011001111001101000100010010001111001001011100010000000111001001011100010101010111001011000011010001101111001101001110110100101111001001011100010000000111001101010110010100001111001111001101010000100111001101001110010111010111001001011110010011010111011111011110010001100111001101000100010010001111001001011110010011010111001011010111110111001111010011000001010100011111001001011100010101010111001011010010110110011111001011010110110101001111001011010110110010000111010001010111110110100111001001011100010001001111001001011100010101010111001011010110110010111111011111011110010011010111001101000100010010001111001111000100010110001111001001011110110100000111000111000000010000010" | |
i=0 | |
for y in range(0,MAX,1): | |
for x in range(0,MAX,1): | |
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") |
运行后发现自己还是太天真,果然不可能是个二维码,感觉又遇到了瓶颈
认真看作者给出的线索,第一位的 1 和其它的字符有些不一样,作者故意把它放大,并且颜色标记为红色,加上屎黄色的背景和其它字符的黑色,像极了小学美术老师教我的 RGB
, 我是不是还漏了什么重要的线索啊
心有猛虎,细嗅蔷薇,假作真时真亦假,无为有处有还无,这几句话感觉也是一条线索
但是我目前并没有其它思路了,因为我只知道它可以转换成其它进制和 ASCII码
,还有转换二维码,摩斯密码这些,暂时想不到其它的方法,有思路的时候再折腾吧