[NCTF 2022]qrssssssss&qrssssssss_revenge WP
本来最近是想练习写 python 脚本的,无意之中刷到了这道题,看到是关于二维码的,于是正好研究一下。
看了官方 WP有些概念没怎么懂,又去借鉴了别人的二维码学习笔记,不过最终还是没看懂官方 Wp 的脚本中的 marklist 是怎么回事。
以下是我的解法:
qrssssssss_revenge
先脚本全部扫描二维码之后,
import os
import cv2
import datetime
import pyzbar.pyzbar as pyzbar# 获取文件的修改时间
def get_modification_time(file_path):return datetime.datetime.fromtimestamp(os.path.getmtime(file_path))# 解码二维码
def decode_qr_code(image_path):image = cv2.imread(image_path)barcodes = pyzbar.decode(image)for barcode in barcodes:return barcode.data.decode("utf-8")return Nonedef main(folder_path):images = []for file in os.listdir(folder_path):if file.lower().endswith((".png", ".jpg", ".jpeg")):file_path = os.path.join(folder_path, file)modification_time = get_modification_time(file_path)images.append((file_path, modification_time))# 按修改时间排序images.sort(key=lambda x: x[1])results = []for image_path, _ in images:qr_content = decode_qr_code(image_path)if qr_content:results.append(qr_content)# 输出到文本文件with open("output.txt", "w", encoding="utf-8") as f:f.write("\n".join(results))print("识别完成,结果已保存到 output.txt")if __name__ == "__main__":folder = input("请输入图片所在文件夹路径: ")main(folder)#这个脚本有一点特殊,是按照图片的修改时间扫码排序输出内容的,因为最开始看的另外一个博主的[WP](http://www.andynoel.xyz/?p=601)#不过不影响下一步操作
将输出内容进行词频分析统计,发现所有字符的频率都是 16 的倍数,所以推断二维码有重复的堆放,

所以我就让 chat 写了个算图片哈希的脚本嘻嘻,删掉相同的冗余的哈希的图片。
import os
import hashlib
from PIL import Image# 计算图片文件的哈希值
def get_image_hash(image_path):hash_md5 = hashlib.md5() # 使用MD5哈希算法try:with open(image_path, "rb") as f:while chunk := f.read(8192): # 每次读取8192字节hash_md5.update(chunk)return hash_md5.hexdigest()except Exception as e:print(f"Error processing file {image_path}: {e}")return None# 删除重复的图片文件
def remove_duplicates(folder_path):seen_hashes = set() # 用来存储已见过的哈希值for root, _, files in os.walk(folder_path):for file in files:# 只处理图片文件if file.lower().endswith(('jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff')):file_path = os.path.join(root, file)file_hash = get_image_hash(file_path)if file_hash is None:continue # 如果计算哈希时出现错误,则跳过该文件if file_hash in seen_hashes:# 如果哈希值重复,删除该文件D:\exercise\NSS\qrssssssss\qrssssssssprint(f"Duplicate found, removing: {file_path}")os.remove(file_path)else:seen_hashes.add(file_hash)if __name__ == "__main__":folder_path = input("Enter the folder path to check for duplicate images: ")if os.path.isdir(folder_path):remove_duplicates(folder_path)print("Duplicate images removal completed.")else:print("The provided path is not a valid directory.")
然后就根据提示 LMQH,二维码的纠错等级+掩码版本的大小来排列二维码内容,具体是纠错等级->掩码版本大小,手撕得到 flag(之后学会写脚本了再进阶一下吧嘿嘿_)
二维码知识借鉴QRcode
qrssssssss
同上思路,也可解得。
不过还可以在这个基础上换一种去除冗余数据的方法,也是一开始就是利用哈希删掉冗余图片,再去爆破。
耶~收工