ヒント:メッセージの送信
ダウンロードして解凍すると、トラフィックパケットと dictionary.txt が 1 つずつあります。
トラフィックには 126 メールボックスから送信されたメールが含まれています。
1 つの圧縮ファイルと 1 つの p.png 画像
import base64
with open('1.txt','r') as f:
d=f.read()
a=base64.b64decode(d)
# print(a.decode('gb2312'))
with open('p.png','wb') as f:
f.write(a)
base64 を 2 進数に変換して保存
別の rar ファイルはパスワードで暗号化されています
import struct, os
png_header = b'\x89PNG\r\n\x1a\n' # 89504e470d0a1a0a
png_ending = b'IEND\xaeB`\x82' # 49454e44ae426082
with open("p.png", 'rb') as f:
data = f.read()
if data[:8] == png_header:
width, height = struct.unpack('>LL', data[16:24])
print('width', width, 'height', height)
for i in range(0,len(data),4):
if data[i:i+8] == png_header:
print('header ',data[i:i+8],i)
if data[i:i+8] == png_ending:
print('ending ',data[i:i+8],i)
def save(a,b):
with open(f'{a}_{b}.png', 'wb') as inp:
inp.write(data[a:b+8])
os.system(f'start {a}_{b}.png')
# save(264,3252)
png のヘッダーとエンディングを分析する
結果
width 100 height 100
header b'\x89PNG\r\n\x1a\n' 0
header b'\x89PNG\r\n\x1a\n' 264
ending b'IEND\xaeB`\x82' 3252
ending b'IEND\xaeB`\x82' 3308
[Finished in 292ms]
ヘッダーとエンディングが 2 つあり、その間の 264〜3252 を png として保存します。save(264,3252)
ヒントの圧縮ファイルのパスワードは 2 つのパスワードを合わせたものです
結合すると解凍パスワードになります
圧縮ファイルには以下が含まれています:
112 個の 100x100 の白黒画像で、その中の 110 - 副本.png を 110.png に変更します(おそらくミスですか?)
2 進数に変換し、ASCII に変換し、その後、辞書に基づいて置換します
import os
from pprint import pprint
from PIL import Image
strr=''
for i in range(1,113):
im=Image.open('./picture/'+str(i)+'.png')
a=im.getpixel((10,10))
if a==(255, 255, 255):
strr+='0'
elif a==(0, 0, 0):
strr+='1'
else:
raise Exception(f'unknown color{a} in {i}.png')
print(strr)
s8=''.join(chr(int(strr[i:i+8],2)) for i in range(0, len(strr), 8))
print(s8)
prex = s8.split('{')[0]
content = s8.split('{')[1].split('}')[0]
print(f'prex-> {prex}')
print(f'content-> {content}')
dic={}
with open('dictionary.txt','r') as f:
aa=[x.replace('\n','') for x in f.readlines()]
for i in aa:
dic.update({i.split(':')[0]:i.split(':')[1]})
pprint(dic)
r=''
for c in content:
r+=dic[c.lower()]
print(f'替换-> {r}')
print('flag-> {}{}'.format(prex,'{'+r+'}'))
結果
0100100101010011010000110100001101111011011010010011001001110011001100000110001100110010011000110011001101111101
ISCC{i2s0c2c3}
prex-> ISCC
content-> i2s0c2c3
{'0': 's',
'1': 'y',
'2': 'b',
'3': 'h',
'4': '7',
'5': 'z',
'6': 'e',
'7': 'p',
'8': 'g',
'9': '9',
'a': 'w',
'b': 'c',
'c': 'l',
'd': 'd',
'e': 'q',
'f': 'm',
'g': 'x',
'h': 'a',
'i': '6',
'j': '2',
'k': 'o',
'l': '5',
'm': 'i',
'n': 'v',
'o': '0',
'p': '3',
'q': 'u',
'r': 'k',
's': 't',
't': 'f',
'u': 'n',
'v': '1',
'w': 'j',
'x': 'r',
'y': '8',
'z': '4'}
替换-> 6btslblh
flag-> ISCC{6btslblh}
[Finished in 869ms]
個々の人のフラグは異なるかもしれませんが、辞書の置換の部分だけが異なるようです。最終的にはISCC{i2s0c2c3}
になります。各人の辞書に基づいて置換してください。