从DDCTF2020-拼图题,学习如何做拼图题
程序员文章站
2022-05-14 08:48:57
...
题目下载
链接:https://pan.baidu.com/s/1BBQw9mOxnrmPm4o68lEpEQ
提取码:i7hm
拿到题目,给了一张图片demo.jpg和一个压缩包,压缩包里为6400个小图片,这6400个小图片是将demo.jpg切割得来的,而flag就在其中几块小图片上。如何找到这几张图片并把它们拼在一起得到flag。
我这里是利用python的CV2库的图像匹配算法,由于修改原图,将flag写入到图片上会造成小图片与原图上相应位置的图片匹配度降低,当匹配度低于某个阈值时,可认为是将flag写到了这张小图片上,我这里阈值取的是1e-10,这个阈值是怎么来的呢,就是先找到一两个有flag片段的小图片来计算匹配度,大概是1e-10这个数量级的。
#python3
from cv2 import cv2
from PIL import Image
import os
import shutil
#读取目标图片
target = cv2.imread(r"C:\Users\Administrator.WQ-20160501NYYU\Downloads\ddctf\file_d0wnl0ad\demo.jpg")
def match(temp_file):
#读取模板图片
template = cv2.imread(temp_file)
#获得模板图片的高宽尺寸
theight, twidth = template.shape[:2]
#执行模板匹配,采用的匹配方式cv2.TM_SQDIFF_NORMED
result = cv2.matchTemplate(target,template,cv2.TM_SQDIFF_NORMED )
#归一化处理
cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 )
#寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
return abs(min_val)
dst_path=r"C:\Users\Administrator.WQ-20160501NYYU\Downloads\233"
dirs = os.listdir(r"C:\Users\Administrator.WQ-20160501NYYU\Downloads\ddctf\file_d0wnl0ad")
count=0
for k in dirs:
if(k.endswith('png')):
count+=1
print("processing on pic"+str(count))
real_path=os.path.join(r"C:\Users\Administrator.WQ-20160501NYYU\Downloads\ddctf\file_d0wnl0ad",k)
rect=match(real_path)
if rect>1e-10:
print(rect)
shutil.move(real_path,dst_path)
else:
continue
最后得到22张小图片,均有flag片段,然后手拼得到flag,当然还可以用其他工具