SHA2017 CTF Writeup

この大会は2017/8/5 19:00(JST)~2017/8/7 7:00(JST)に開催されました。
今回もチームで参戦。結果は1800点で462チーム中26位でした。
自分で解けた問題をWriteupとして書いておきます。

Stack Overflow (Crypto 100)

添付のPythonコードを見ると、カウンタの値が固定。CTRモードの場合、ナンス+カウンタを暗号鍵で暗号化し、平文とXORを取るが、この問題ではナンス+カウンタが固定。つまり、暗号化したタイミングでは16バイトのブロックごとに同じ値になる。
16バイトの不明なXOR鍵で暗号化されているので、PDFのファイルフォーマットと照らし合わせながら、鍵を突き止め、復号する。

with open('flag.pdf.enc', 'rb') as f:
    data = f.read()

PDF_0_6 = '%PDF-1.'
PDF_12_15 = '\x0a%%E'
PDF_11 = ' '
PDF_07_10 = 'obj\x0a'

key_0_6 = []
for i in range(len(PDF_0_6)):
    code = ord(PDF_0_6[i]) ^ ord(data[i])
    key_0_6.append(code)

key_12_15 = []
for i in range(len(PDF_12_15)):
    code = ord(PDF_12_15[i]) ^ ord(data[i-7])
    key_12_15.append(code)

key_11 = []
for i in range(len(PDF_11)):
    code = ord(PDF_11[i]) ^ ord(data[i+11])
    key_11.append(code)

key_07_10 = []
for i in range(len(PDF_07_10)):
    code = ord(PDF_07_10[i]) ^ ord(data[i+55])
    key_07_10.append(code)

key = []
for i in range(len(key_0_6)):
    key.append(key_0_6[i])
for i in range(len(key_07_10)):
    key.append(key_07_10[i])
for i in range(len(key_11)):
    key.append(key_11[i])
for i in range(len(key_12_15)):
    key.append(key_12_15[i])

flag = ''
for i in range(len(data)):
    code = ord(data[i]) ^ key[i%len(key)]
    flag += chr(code)

with open('flag.pdf', 'wb') as f:
    f.write(flag)

f:id:satou-y:20170816215137p:plain

FLAG{15AD69452103C5DF1CF61E9D98893492}