この大会は2016/10/1 1:00(JST)~2016/10/3 1:00(JST)に開催されました。
今回もチームで参戦。結果は557点で836チーム中50位でした。
自分で解けた問題をWriteupとして書いておきます。
thejoyofpainting(stego 50)
flacファイルが与えられているので、Audacityで開いてみる。スペクトグラム表示にし、サンプリングを16000Hzにしたら、フラグが出てきた。
hxp{/!\-1'm-f0ur13r0uZ-/!\}
haggis(crypto 100)
コードが与えられているので、読み解く。
AES暗号で最後のブロックの暗号と、最初の方の平文が与えられているので、その条件を満たせば、フラグが表示される。
4ブロック前提に試すと条件を満たすものがないので、5ブロック前提に考える。
plain1: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x<16進表記の平文長>' plain2: 'I solemnly swear' plain3: ' that I am up to' plain4: ' no good.\0??????' plain5: '????????????????'
plain5はできるだけいろんなデータを受け入れたいため、パディングは最後の1文字だけで'\x01'前提。
plain4はできるだけ固定長を長くする。
plain4: ' no good.\0XXXXX?'(最後の1文字だけブルートフォース)
ただ、これだと該当する平文が見つからない場合があるので、以下のように考える。
plain4: ' no good.\0XXXX??'(最後の2文字だけブルートフォース)
この前提で5ブロック目の暗号を復号したものと、4ブロック目の平文とのXORが5ブロック目の平文になることを利用し、最後の1文字が'\x01'になるものをブルートフォースで探すスクリプトを書く。
#!/usr/bin/env python3 import socket import binascii from Crypto.Cipher import AES pad = lambda m: m + bytes([16 - len(m) % 16] * (16 - len(m) % 16)) def haggis_all(m): crypt0r = AES.new(bytes(0x10), AES.MODE_CBC, bytes(0x10)) return crypt0r.encrypt(len(m).to_bytes(0x10, 'big') + pad(m)) def aes_decrypt(m): crypt0r = AES.new(bytes(0x10), AES.MODE_ECB) return crypt0r.decrypt(m) def sxor(x, y): s1 = binascii.hexlify(x) s2 = binascii.hexlify(y) ixor = int(s1, 16) ^ int(s2, 16) return binascii.unhexlify(hex(ixor)[2:].zfill(32)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('104.198.243.170', 2501)) target = s.recv(256).strip(b'\n') print(b'target = ' + target) d_target = aes_decrypt(binascii.unhexlify(target)) msg_head = b'I solemnly swear that I am up to no good.\0' msg_fix = b'XXXX' msg_tmp = b'000000000000000' found = 0 for i in range(256): for j in range(256): msg = msg_head + msg_fix + chr(i).encode() + chr(j).encode() + msg_tmp e = haggis_all(msg) c4 = e[48:64] p5 = sxor(d_target, c4) if p5[-1:] == b'\x01': msg = msg_head + msg_fix + chr(i).encode() + chr(j).encode() + p5[:-1] found = 1 break if found == 1: break h_msg = binascii.hexlify(msg) print(h_msg) s.sendall(h_msg + b'\n') data = s.recv(256) print(data)
hxp{PLz_us3_7h3_Ri9h7_PRiM1TiV3z}