この大会は2020/8/29 19:00(JST)~2020/8/31 19:00(JST)に開催されました。
今回もチームで参戦。結果は359点で519チーム中156位でした。
自分で解けた問題をWriteupとして書いておきます。
SignIN (Misc)
切り貼りすると、QRコードになる。
このQRコードを読み込む。
welc0me_t0_GACTF_have_Fun
GACTF{welc0me_t0_GACTF_have_Fun}
ezAES (Crypto)
keyは2バイトだけが不明。
SECRET: keyで決まる10バイト message: 86バイト 暗号化 0 1 2 3 4 5 6 7 8 9 a b c d e f a8**************************b1a9 23**************************0111 47**************************6e09 4e**************************cdb1 c7**********a32c412a3e7474e584cd 72481dab9dd83141706925d92bdd39e4 [平文1ブロック目] ^ IV --(暗号化)--> [暗号文1ブロック目] [平文2ブロック目] ^ [暗号文1ブロック目] --(暗号化)--> [暗号文2ブロック目] [平文3ブロック目] ^ [暗号文2ブロック目] --(暗号化)--> [暗号文3ブロック目] [平文4ブロック目] ^ [暗号文3ブロック目] --(暗号化)--> [暗号文4ブロック目] [平文5ブロック目] ^ [暗号文4ブロック目] --(暗号化)--> [暗号文5ブロック目] [平文6ブロック目] ^ [暗号文5ブロック目] --(暗号化)--> [暗号文6ブロック目]
最後の16バイトの暗号化が分かっているので、ブルートフォースでそれを復号する。
チェック内容は以下の条件を満たすかどうかになる。
・平文6ブロック目の1バイト目と暗号文5ブロック目の1バイト目のXORが復号データの1バイト目 ・平文6ブロック目の末尾10バイトと暗号文5ブロック目の末尾10バイトのXORが復号データの末尾10バイト
keyがわかったら、後ろのブロックから復号していくと、平文1ブロック目とIVのXORがわかる。平文1ブロック目とのXORによりIVがわかるので、それがフラグになる。
from Crypto.Cipher import AES import itertools import string import hashlib def pad(s): p = 16 - len(s) % 16 return s + chr(p) * p def str_xor(s1, s2): return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2)) def get_msg(key): msg = 'AES CBC Mode is commonly used in data encryption. What do you know about it?' msg += hashlib.md5(key).digest()[:10] return msg c5 = '72481dab9dd83141706925d92bdd39e4'.decode('hex') c4_1 = 'c7'.decode('hex') c4_2 = 'a32c412a3e7474e584cd'.decode('hex') for c in itertools.product(string.letters + string.digits, repeat=2): key = 'T0EyZaLRzQmNe2' + ''.join(c) pad_msg4 = pad(get_msg(key))[-16:] aes = AES.new(key, AES.MODE_ECB) dec = aes.decrypt(c5) if str_xor(c4_1, pad_msg4[0]) == dec[0] \ and str_xor(c4_2, pad_msg4[-10:]) == dec[-10:]: break print '[+] key =', key pad_msg = pad(get_msg(key)) pt_blocks = [pad_msg[i:i+16] for i in range(0, len(pad_msg), 16)] ct_block = c5 for i in range(5): aes = AES.new(key, AES.MODE_ECB) dec = aes.decrypt(ct_block) ct_block = str_xor(dec, pt_blocks[-i-1]) print '[+] ct_block =', ct_block.encode('hex') aes = AES.new(key, AES.MODE_ECB) dec = aes.decrypt(ct_block) IV = str_xor(dec, pt_blocks[0]) flag = 'gactf{%s}' % IV print flag
実行結果は以下の通り。
[+] key = T0EyZaLRzQmNe2pd [+] ct_block = c70b38bbd268a32c412a3e7474e584cd [+] ct_block = 4eea629633f4d9589791ac584817cdb1 [+] ct_block = 4765763869a74c4d22538ad4489c6e09 [+] ct_block = 233f21c19790307c1f0b551b29640111 [+] ct_block = a884ed307a7af7b003e81c46b928b1a9 gactf{9j_for_aes_cbc!!}
gactf{9j_for_aes_cbc!!}