从DDCTF2020-拼图题,学习如何做拼图题

题目下载
链接: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,当然还可以用其他工具
从DDCTF2020-拼图题,学习如何做拼图题_第1张图片

从DDCTF2020-拼图题,学习如何做拼图题_第2张图片

你可能感兴趣的:(Misc)