
Harvey
前言:比赛当天没空,不过事后听Lumos师傅说里面题目挺有意思的,于是就决定今天复现一波(后附2021“春秋杯”新年欢乐赛的解题思路)
感谢@i_kei师傅供题
刀、枪、剑、戟、斧、钺、钩、叉、鞭、锏、锤、戈、镋、棍、槊、棒、矛、耙Hint1:JPHS
Hint2:用Notepad++打开试试?
Hint3:前十种兵器对应10进制,后八种对应8进制
根据名字加个后缀.rar,再根据压缩包提示2021牛年大吉解压得到十八般兵器的图片
接着JPHS隐写并根据题目依次排序得到一串数字
136143999223163525817639797858700963935
3044053720460556276610613346353724230575
然后前十个十进制转十六进制,后八个八进制转十六进制得到字符串
666c61677b43544673686f775f31305f62415f42616e5f62316e675f51317d
最后hex解码得到flag
flag{CTFshow_10_bA_Ban_b1ng_Q1}
flag为全部小写字母,没有空格
@感谢cheyenne师傅供题
经典老套娃了,分离出四张图片
根据扫码得到的信息可知关键在第二张图片,将其放入steg
很明显比对猪圈密码表得到flag:flag{dajiadoaidjb}
题目下载 蓝奏云下载地址:https://wws.lanzous.com/i1Ac0jybrvc 百度云下载地址: https://pan.baidu.com/s/14EXw7U4w0Am0oP_xRXfbqQ 提取码:ns2k
感谢i_kei师傅供题Hint1:不要格式化哟,看看引导扇区是不是丢东西了
Hint2:压缩包密码在图片文件头里
vhd直接打开发现不能装载(引导扇区全部被抹除),于是用winhex打开读取发现有张图片和压缩包
压缩包密码就是图片的文件头89504E47,最终得到flag:flag{CTFshow_The_Year_of_the_Ox}
简单的FM
感谢@阿狸师傅供题
在复现了ing...(0%
一曲童话镇,多少断肠人? https://ctfshow.lanzous.com/iA8HFkn4q9c
感谢@阿狸师傅供题hint1:离别
hint2:思念
hint3:爱
hint4:印象
binwalk分离出一个加密的压缩包
爆破得到密码:67373
接着就是算法这块了2333~(KNN)
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from ast import literal_eval
from PIL import Image
x_train = []
y_train = []
x_test = []
f1 = open("t.txt","r")
f2 = open("flag.txt","r")
while 1:
s = f1.readline()
if not s:
break
s = s.strip('\n')
p1 = literal_eval(s.split("\t")[1])
p2 = literal_eval(s.split("\t")[0])
x_train.append(p1)
x_test.append(p2)
#print(x_train)
#print(x_test)
while 1:
s = f2.readline()
if not s:
break
s = s.strip('\n')
s = literal_eval(s)
y_train.append(s)
#print(y_train)
x_train = np.array(x_train)
y_train = np.array(y_train)
x_test = np.array(x_test)
clf = KNeighborsClassifier(n_neighbors = 1)
clf.fit(x_train, x_test)
y_test = clf.predict(y_train)
f3 = open("3.txt","w")
for i in y_test:
f3.write(str(y_test[i]))
f3.close()
from PIL import Image
fp = open("3.txt","r").read()
pic = Image.new("L", (991, 79))
i = 0
for y in range(79):
for x in range(991):
if fp[i] == '0':
pic.putpixel([x,y], 255)
else:
pic.putpixel([x,y], 0)
i += 1
pic.show()
欢迎使用色图生成器
已获取flag,正在为您生成色图……
色图生成完毕,准备传输
正在传输色图……
ERROR! 检测到屏蔽系统,传输被中断
准备为色图打码
正在生成马赛克……
打码完成,准备添加冗余数据……
添加完成,正在打包……
打包完成,准备传输……
传输完成,请点击下方链接下载您的色图
感谢@cheyenne师傅供题Hint1:颜色很重要,但github更重要
Hint2:第一步图片很重要,txt不重要
Hint3:看一看马赛克部分的RGB值,有没有想到什么呢
在复现了ing...(0%
有手就行,没手的可以拿眼睛去瞪
感谢@nimda师傅供题
chrome插件Save All Resources将其下载进行拼图
跑下脚本得到flag:flag{f4864ce0-18d6-4e45-bb51-08a9d47de97f}
脚本附上:
import json
import os
from PIL import Image
# 模板图:运行目录下的 model.png
# 新建 output 和 blocks 文件夹
# 拼图切片放在 blocks 文件夹中
# 常量设置在 79 行
# PIECES = 225 切片总数
# SQURE_LENGTH = 42 切片边长
# Squeeze Model Picture into pieces
# Returns the path to the folder which contains pictures taged as 1.png, 2.png
def ModelPictureSqueeze(filePath, population, lengthSqueezeSquare):
modelImg = Image.open(filePath)
width, height = modelImg.size
widthSqueezeCount = width // lengthSqueezeSquare # squeeze count from long side
heightSqueezeCount = height // lengthSqueezeSquare
storageDir = os.path.dirname(os.path.realpath(filePath))
os.mkdir(storageDir + "\\model")
regions = []
for i in range(heightSqueezeCount):
for j in range(widthSqueezeCount):
box = (lengthSqueezeSquare * j, lengthSqueezeSquare * i, lengthSqueezeSquare * (j + 1), lengthSqueezeSquare * (i + 1))
region = modelImg.crop(box)
regions.append(region)
region.save(storageDir + '\\model\\{}.{}{}.png'.format(i, j, ".L" if j == (widthSqueezeCount - 1) and (i + 1) * (j + 1) != population else ".E" if (i + 1) * (j + 1) == population else ""))
return regions, widthSqueezeCount
# Fetch nine points as a sample
def NinePointSamplingAnalyze(image):
width, height = image.size
imgObject = image.convert("RGB")
pixels = imgObject.load()
samplings = []
for i in range(3):
for j in range(3):
samplePixel = pixels[(width - 1) if j == 2 else (width // 2) * j, (height - 1) if i == 2 else (height // 2) * i]
samplings.append(samplePixel)
image.close()
return samplings
# Match one model sample with one puzzle sample
def SamplingMatch(modelSample, sample):
flag = 0
for i in range(9):
if sample[i] == modelSample["sample"][i]:
flag += 1
return flag
# Find out the best match with rotate
def SamplingBestRotate(modelSample, sample):
flags = []
for i in range(4):
flags.append(SamplingMatch(modelSample, sample))
sample = SamplingRotate(sample)
return max(flags), flags.index(max(flags)) * (-90)
# Rotate a sample
def SamplingRotate(sample):
newSamplings = []
index = [6, 3, 0, 7, 4, 1, 8, 5, 2]
for i in range(9):
newSamplings.append(sample[index[i]])
return newSamplings
# Find a best match with rotate and parse to data for a puzzle sample
def SamplingBestSolve(modelSamplings, sample):
flags = []
degrees = []
for i in range(len(modelSamplings)):
flag, degree = SamplingBestRotate(modelSamplings[i], sample)
flags.append(flag)
degrees.append(degree)
return max(flags), flags.index(max(flags)), degrees[flags.index(max(flags))]
# squeeze model and parse to JSON
PIECES = 225
SQURE_LENGTH = 42
modelRegions, widthPieceCount = ModelPictureSqueeze("model.png", PIECES, SQURE_LENGTH)
modelSamplings = []
for i in range(len(modelRegions)):
modelSamplings.append({
"flag": 2 if (i == len(modelRegions) - 1) else 1 if ((i + 1) % widthPieceCount) == 0 else 0,
"sample": NinePointSamplingAnalyze(modelRegions[i])
})
jsonData = json.dumps(modelSamplings)
print(jsonData)
# process puzzle
samplings = []
files = os.listdir("blocks/")
for i in range(len(files)):
img = Image.open("blocks/" + files[i])
samplings.append({
"flag": 0,
"rotate": 0,
"sample": NinePointSamplingAnalyze(img),
"oldFileName": files[i],
"newFileName": ""
})
jsonData = json.dumps(samplings)
print(jsonData)
# prepare fileName
for i in range(len(samplings)):
samplings[i]["flag"], fileIndex, samplings[i]["rotate"] = SamplingBestSolve(modelSamplings, samplings[i]["sample"])
samplings[i]["newFileName"] = '{}.{}{}.png'.format(fileIndex // widthPieceCount, fileIndex % widthPieceCount, '.E' if fileIndex // widthPieceCount == widthPieceCount - 1 and fileIndex % widthPieceCount == widthPieceCount - 1 else '.L' if fileIndex % widthPieceCount == widthPieceCount - 1 else "")
jsonData = json.dumps(samplings)
print(jsonData)
heightPieceCount = PIECES // widthPieceCount
composeImg = Image.new("RGB", (heightPieceCount * SQURE_LENGTH, widthPieceCount * SQURE_LENGTH))
for i in range(len(samplings)):
img = Image.open("blocks/" + samplings[i]["oldFileName"])
img = img.rotate(samplings[i]["rotate"])
positionY = int(samplings[i]["newFileName"].split(".")[0])
positionX = int(samplings[i]["newFileName"].split(".")[1])
composeImg.paste(img, (positionX * SQURE_LENGTH, positionY * SQURE_LENGTH))
composeImg.save("output/result.png")
这是从一处寺庙遗址中得到的碑文拓片,你能从中发现什么吗? https://ctfshow.lanzous.com/iSFN4kn5jna
感谢@cheyenne师傅供题Hint1、为什么碑文上空白的地方,拓片上却是黑黑一片呢?
Hint2、如果说每个方块对应一个字符,可是替换表在哪里?
先将图片反色:在线工具
然后放入steg lsb发现一个PNG
save bin保存并修改下头文件得到
接着将图中与六十四卦图相比对
得到如下信息:
晋 噬嗑 井 复 谦 丰
渐 大过 睽 巽 无妄 屯
中孚 观 归妹 革 坎 颐
革 明夷 否 泰 明夷
根据题目所给的图得到对应的数字
5 37 26 32 8 44
11 30 53 27 39 34
51 3 52 46 18 33
46 40 7 56 40
对照base64编码表得到flag:flag{Le1bnizD0uShuoH4o}
在一台旧电脑上(大约在16位操作系统还能跑的年代)发现了这个文件,挖掘它的秘密
感谢@ThTsOd师傅供题Hint:请仔细阅读题目描述(5毛一条,去掉括号)
研究ing(0%
万物皆有"FUN",电脑扫"FUN"活动,提供大写的"FUN"字样,即可获取flag~
附件(提取码:2als)
对着摄像头扫描带有“FUN”的字样即可获得flag
但愿你能解出密文,不然我就会继续犯罪:)
本题获取flag提交前请加上flag{}
根据题目所描述的可知是黄道十二宫案件中的加密方式
先把图中的密文列出来
^#@$@#()/>@?==%1(
!)>(*+3<#86@-7$^.
4&)8%#&6!=%1#$-$
+5&?#!.03!%=@=101
0?(*~#??.+)%&.7^8
=1%^=$5$7@@8>&9
9@0185(+7)<%3#@^4
&@@<.)#3#%%<<++
@.?=~**+!==65^@&
附上脚本
s1=r'^#@$@#()/>@?==%1('*9
s2=r'!)>(*+3<#86@-7$^.'*9
s3=r'4&)8%#5&6!=%1#$-$'*9
s4=r'+5&?#!.03!%=@=101'*9
s5=r'0?(*~#??.+)%&.7^8'*9
s6=r'=1%*^=$5$7@@8>&*9'*9
s7=r'9@0185(+7)<%3#@^4'*9
s8=r'&@@<.)#3*#%%<<*++'*9
s9=r'.@.?=~**+!==65^@&'*9
tmp=''
for i in range(17):
tmp += s1[i]+s2[i+2]+s3[i+4]+s4[i+6]+s5[i+8]+s6[i+10]+s7[i+12]+s8[i+14]+s9[i+16]
def cut(obj, sec):
str_list = [obj[i:i+sec] for i in range(0,len(obj),sec)]
print(str_list)
return str_list
l1=cut(tmp,17)
for i in l1:
print (i)
跑一下得到如下信息
最后使用工具AZdecrypt解密得到flag:flag{WUUHUUTAKEOFF}
拼图的好处:
1、动手又动脑,开发智力,增加几何空间感
2、你可以在拼好后的作品上发挥想象,绘上与众不同的色彩,这样,你的作品就成了独一无二的艺术品了。
3、与家人或朋友一起拼装,增加了交流,增进感情与亲情
这么多的益处,所以赶紧来玩吧~附件(提取码:l1hs)
手工拼图,将有字的碎片单独提取出来
利用PS进行拼图得到flag:flag{w9w45my6x8kk4e8gp9nqm6j2c154wad49}
三合一收款
下面三种方式都支持哦
Harvey
https://blog.harvey.plus/index.php/Writeup/83.html(转载时请注明本文出处及文章链接)
请严格遵守网络安全法相关条例!一切分享仅用于学习!一切违法行为皆与本站无关!
大佬,我想问一下,你那个拼图v2.0使用的什么脚本呀,能教教我吗
已上传
师傅情人节还在肝题呀qwq