この大会は2020/4/1 9:00(JST)~2020/4/2 9:00(JST)に開催されました。
今回もチームで参戦。結果は126点で527チーム中276位でした。
自分で解けた問題をWriteupとして書いておきます。
Sanity (misc)
freenodeで#midnightsunチャネルに入ると、メッセージにフラグがあった。
midnight{n0_c0ugh1ng_0n_1rc}
Pybonhash (crypto, re)
pycをデコンパイルする。
$ uncompyle6 pybonhash.cpython-36.pyc # uncompyle6 version 3.6.5 # Python bytecode 3.6 (3379) # Decompiled from: Python 2.7.12 (default, Oct 8 2019, 14:14:10) # [GCC 5.4.0 20160609] # Warning: this version has problems handling the Python 3 byte type in contants properly. # Embedded file name: pybonhash.py # Compiled at: 2020-03-28 22:11:38 # Size of source mod 2**32: 1017 bytes import string, sys, hashlib, binascii from Crypto.Cipher import AES from flag import key if not len(key) == 42: raise AssertionError else: data = open(sys.argv[1], 'rb').read() if not len(data) >= 191: raise AssertionError FIBOFFSET = 4919 MAXFIBSIZE = len(key) + len(data) + FIBOFFSET def fibseq(n): out = [ 0, 1] for i in range(2, n): out += [out[(i - 1)] + out[(i - 2)]] return out FIB = fibseq(MAXFIBSIZE) i = 0 output = '' while i < len(data): data1 = data[(FIB[i] % len(data))] key1 = key[((i + FIB[(FIBOFFSET + i)]) % len(key))] i += 1 data2 = data[(FIB[i] % len(data))] key2 = key[((i + FIB[(FIBOFFSET + i)]) % len(key))] i += 1 tohash = bytes([data1, data2]) toencrypt = hashlib.md5(tohash).hexdigest() thiskey = bytes([key1, key2]) * 16 cipher = AES.new(thiskey, AES.MODE_ECB) enc = cipher.encrypt(toencrypt) output += binascii.hexlify(enc).decode('ascii') print(output) # okay decompiling pybonhash.cpython-36.pyc
これから以下のことが読み取れる。
・keyの長さは42 ・dataの長さは191以上 ・FIB: フィボナッチ数列
総当たりでAES復号して、md5の32バイトになるものを探す。そこからさらに2バイト文字でそのmd5になるものを探す。そこから鍵を割り出すことができれば、フラグが取得できる。
from Crypto.Cipher import AES import hashlib def fibseq(n): out = [0, 1] for i in range(2, n): out += [out[(i - 1)] + out[(i - 2)]] return out def is_hash(s): chars = '0123456789abcdef' for c in s: if c not in chars: return False return True def rev_hash(h): for code1 in range(256): for code2 in range(256): text = chr(code1) + chr(code2) if hashlib.md5(text).hexdigest() == h: return text return 'Error' FIBOFFSET = 4919 LEN_KEY = 42 LEN_DATA = 191 MAXFIBSIZE = LEN_KEY + LEN_DATA + FIBOFFSET FIB = fibseq(MAXFIBSIZE) with open('hash.txt', 'r') as f: output = f.read().rstrip() msg = '' j = 0 key = [0] * LEN_KEY for i in range(0, len(output), 64): enc = output[i:i+64].decode('hex') found = False for key1 in range(256): for key2 in range(256): thiskey = (chr(key1) + chr(key2)) * 16 cipher = AES.new(thiskey, AES.MODE_ECB) dec = cipher.decrypt(enc) if is_hash(dec): found = True h = dec if j < LEN_DATA: key[(j + FIB[(FIBOFFSET + j)]) % LEN_KEY] = key1 j += 1 key[(j + FIB[(FIBOFFSET + j)]) % LEN_KEY] = key2 j += 1 break if found: break msg += rev_hash(h) print msg flag = '' for k in key: flag += chr(k) print flag
実行結果は以下の通り。
Wee'r n Intkneg nrm o ms ihkw n u' tsuwnii'kn eorenAwWwwnoree nt'ti wgsk ouenm Akhies e yrI ue kfnn ne n' eWee'r n Intkneg nrm o ms ihkw n u' tsuwnii'kn eorenAwWwwnoree nt'ti wgsk ouenm Akhies e midnight{xwJjPw4Vp0Zl19xIdaNuz6zTeMQ1wlNP}
midnight{xwJjPw4Vp0Zl19xIdaNuz6zTeMQ1wlNP}