[SECCON BEGINNERS CTF 2021] depixelization

Can you depixelize it ?

問題

convert.pyという与えられた文字列をマスク(?)し難読化するスクリプトが与えられます。またこのスクリプトを利用して難読化されたFLAGの画像ファイルも与えられます。
あとはただ読んでいくだけです。

解法

d.pngには\x20から\x7eまでの文字列''.join([chr(i) for i in range(0x20, 0x7e+1)])をconvert.pyしたものが入っています。
これを下のスクリプトに通しました。

from PIL import Image
import numpy as np
mt_map = {}

# read all

z = ''.join([chr(i) for i in range(0x20, 0x7e+1)])
img = Image.open('./d.png')
alphabets = [[] for i in range(len(z))]
a = np.array(img)
for i in range(len(z)):
    for h in range(100):
        alphabets[i].append(a[h][i * 85:(i+1)*85])

for i, alp in enumerate(alphabets):
    mt_map[z[i]] = np.array(alp)

# # solve

alphabets = [[] for i in range(31)]
img = Image.open('./output.png')
a = np.array(img)
for i in range(31):
    for h in range(100):
        alphabets[i].append(a[h][i * 85:(i+1)*85])

# debug
# for key, val in mt_map.items():
#     Image.fromarray(np.array(val)).save(f'dev/{key}.png')

for ind, val in enumerate(alphabets):
    print(f'oT: {ind}')
    try:
        Image.fromarray(np.array(val)).save(f'dev/out_{ind}.png')
    except:
        pass

d = [None for i in range(31)]
for ind, alp in enumerate(alphabets):
    candidate_cnt = 0
    for key, val in mt_map.items():
        c = 0
        for i in range(100):
            if np.array_equal(val[i],alp[i]):
                c+=1
        if c == 100:
            print(key)
            d[ind] = key
            candidate_cnt += 1

    if candidate_cnt != 1:
        print(f'atama okasi narude {candidate_cnt} {alp}')

f = ''.join(d)
print(f'flag?: {f}')

flag

flag?: ctf4b{1f_y0u_p1x_y0u_c4n_d3p1x}