【MISC】一道假的二維碼題目學習zxing庫[python解讀二維碼]

folio發表於2024-06-01

引言

這道題目的考點是檔案格式、雙圖差值、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搞定了,也把這兩週的負面情緒掃掃空。

落之~

相關文章