【MISC】一道假的二维码题目学习zxing库[python解读二维码]

引言

这道题目的考点是文件格式、双图差值、Ook!编码、PRC等,我做这题的重点是复习巩固python读取二维码zxing库的使用。

例题

┌───────────────────────────────────────────────────┐
│                   马老师的秘籍                      │
│                                                   │
│   DASCTF2020 圣诞赛 Misc题目                        │
│                                                   │ 
└───────────────────────────────────────────────────┘
ps:考虑到某公司的不分享精神或许会有版权之类的争端,文件的解密需要你ctf一下,哈哈!

提取码:pZrX

Writeup(WP)

  1. 打开图像《马老师的秘籍.png》是一排排的二维码,扫描一下看看:
    一排排二维码
    【注意】真正解题不要扫描这些二维码(网上流行马保国的一段话而已,跟做题没有关系),就是一个浪费时间的坑
    二维码批量扫描
  2. 查看图像《马老师的秘籍.png》二进制,发现PK压缩包,手动或者使用foremost分解出zip包《00002236.zip》,使用winrar可以看到里面有3个加密的文件,但用其它压缩软件如360zip查看却是乱码:
    压缩包
  3. 二进制查看《00002236.zip》发现伪加密,9改为0,zip包恢复:
    伪加密
  4. 解压出《马老师的奇妙棋盘.jpg》,折腾一会儿发现是双图差值,跟《马老师的秘籍.png》XOR:
    奇妙棋盘
    双图
  5. 根据提示md5(NianQingRenBuJiangWuDe)=c57988283c92f759585a0c1aebfdd743,得到解压密码解开《00002236.zip》
    md5
    prc
  6. 写脚本得到Ook!密文,解密得到flag:
    Ook

    本题得解。

相关脚本

图片分隔

from PIL import Image, ImageDraw

# 创建一个 400x400 的黑色像素图
#image = Image.new('RGB', (400, 400), (255, 255, 255))
img = Image.open("马老师的秘籍.png")
img_size = img.size
print(img_size) 
w = img_size[0]  # 图片宽度
h = img_size[1]  # 图片高度
# 数一数得到二维码的边长为99
'''
# 创建一个 ImageDraw 对象
draw = ImageDraw.Draw(img)

# 纵向
qidian=0
kuand=99
jiange=0
while qidian+kuand<w:
    draw.line((qidian,0,qidian,h),fill=(255, 0, 0),width=1)
    draw.line((qidian+kuand,0,qidian+kuand,h),fill=(0,255,0),width=1)
    qidian += (kuand+jiange)

# 横向
qidian=0
kuand=99
jiange=0
while qidian+kuand<h:
    draw.line((0,qidian,w,qidian),fill=(0, 0,255),width=1)
    draw.line((0,qidian+kuand,w,qidian+kuand),fill=(0,255, 0),width=1)
    qidian += (kuand+jiange)

# 保存图像
img.save('key.png')
'''
n=0
wq=hq=0
side =99
while side+hq<=h:
    wq=0
    while side+wq<=w:
        img_name = f'./qrcodes/'+str(n).zfill(3)+'.png'
        cropped = img.crop((wq, hq, wq+side, hq+side))
        cropped.save(img_name)
        n+=1
        # cropped.show()
        wq+=side
    hq+=side

二维码批量读取

import zxing    #导入解析包

reader = zxing.BarCodeReader()
imgs = glob.glob(r'./qrcodes/*.png')
#print(imgs)

# 测试【注意】zxing被我给修改了,直接安装的不能用,详见下方的扩展
#print(reader.decode(imgs[0],encoding='gb18030').parsed)

# 一个一个读,很慢!
'''
msg=''
for i in imgs:
    msg += reader.decode(i).parsed
'''
# 批量读取
info = reader.decode(imgs,encoding='gb18030')
msg =  ''.join([x.parsed for x in info])
print(msg)

一一替换

with open('GoodLuck.txt',encoding='utf-8') as k:
    key = k.read().split('\n')
with open('闪电五连鞭.txt',encoding='utf-8') as c:
    cipher = c.read()

k={}
for i in key:
    t=i.split(' -> ')
    k[t[0]]=t[1]
    cipher=cipher.replace(t[0],t[1])
print(cipher)

扩展知识点

zxing库在windows上整合

  1. zxing安装:
> pip install zxing
> pip list zxing | findstr "zxing"
zxing                              1.0.3
  1. zxing安装目录D:\\coding\\Anaconda3\\lib\\site-packages\\zxing
  2. 错误修正
3.1. 报错:zxing.BarCodeReaderException: ('Java JARs not found in classpath ...)
找到__init__.py文件中的class BarCodeReader(object):
里面关于文件路径分隔符的判断:classpath_sep = ';' if sys.platform == 'nt' else ':'  # https://stackoverflow.com/a/60211688
【修正】 因为我们是在windows里面用,直接改为 classpath_sep = ';' 即可。

3.2. 报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdf in position 0: invalid continuation byte
找到__init__.py文件中的class BarCodeReader的decode函数中codes = [BarCode.parse(result) for result in file_results]
使用了BarCode.parse(result)中有两处bytes.decode()调用,显然是utf-8与中文编码GB18030/GBK/GB2312 不兼容导致
        parsed = parsed[:-1].decode()
        raw = raw[:-1].decode()
【修正】 增加一个参数,改动如下:
BarCode.parse(cls, zxing_output, encoding='utf-8'):
        parsed = parsed[:-1].decode(encoding)
        raw = raw[:-1].decode(encoding)
BarCodeReader.(self, filenames, try_harder=False, possible_formats=None, pure_barcode=False, products_only=False, encoding='utf-8'):
        codes = [BarCode.parse(result, encoding=encoding) for result in file_results]
【使用】可以传参编码方式:zxing.BarCodeReader().decode(imgs[0],encoding='GBK')

PS使用之图层操作

  1. 打开ps,文件>打开:
    open
  2. 打开第一张图片,新建一个图层(Ctrl+Shfit+N),隐藏“背景”图层,放大编辑窗口:
    img1
    big
  3. 再打开第二张图片,Ctrl+A复制图层:
    copy
  4. 回到第一张图片,图层1中Ctrl+V粘贴:
    paste
  5. 图层1选择“差值”
    diff
    info

结束语

今天是儿童节又是周末,天公作美,一早就下起了大雨,吃过早饭,写点代码,把zxing搞定了,也把这两周的负面情绪扫扫空。

落之~
posted @ 2024-06-01 13:00  folio  阅读(88)  评论(0编辑  收藏  举报