この大会は2021/8/28 8:00(JST)~2021/8/29 20:00(JST)に開催されました。
今回もチームで参戦。結果は1890点で157チーム中22位でした。
自分で解けた問題をWriteupとして書いておきます。
discrete log (warmup, crypto)
フラグの各文字について、以下のように暗号化している。
pow(g, r*m, p)
rは未知だが、以下の式が成り立つので、pow(g, r, p)が算出できる。
pow(g, r*m, p) = pow(pow(g, r, p), m, p)
あとはmをブルートフォースで割り出せばフラグが求められる。
from Crypto.Util.number import * with open('output.txt', 'r') as f: p = int(f.readline().rstrip()) g = int(f.readline().rstrip()) cs = eval(f.readline().rstrip()) d = inverse(ord('C'), p - 1) g_r0 = pow(cs[0], d, p) d = inverse(ord('a'), p - 1) g_r1 = pow(cs[1], d, p) assert g_r0 == g_r1 g_r = g_r0 flag = '' for c in cs: for code in range(32, 127): if pow(g_r, code, p) == c: flag += chr(code) break print flag
CakeCTF{ba37a0f409ef3ec23a6cffbc474a1cef}
improvisation (crypto)
LFSRの問題。rをz3で求め、復号する。
from z3 import * from Crypto.Util.number import * def LFSR(r): while True: yield r & 1 b = (r & 1) ^\ ((r & 2) >> 1) ^\ ((r & 8) >> 3) ^\ ((r & 16) >> 4) r = (r >> 1) | (b << 63) r = BitVec('r', 64) lfsr = LFSR(r) flag_head = 'CakeCTF{' m = bytes_to_long(flag_head[::-1]) ## add '0' to arrange b_ct = '0' + bin(0x58566f59979e98e5f2f3ecea26cfb0319bc9186e206d6b33e933f3508e39e41bb771e4af053)[2:] s = Solver() for i in range(len(flag_head) * 8): s.add(((m & 1) ^ next(lfsr)) == int(b_ct[i])) m >>= 1 res = s.check() if res == sat: m = s.model() r = m[r].as_long() else: exit(1) lfsr = LFSR(r) bin_flag = '' for i in range(len(b_ct)): b = int(b_ct[i]) ^ next(lfsr) bin_flag = str(b) + bin_flag flag = long_to_bytes(int(bin_flag, 2))[::-1] print flag
CakeCTF{d0n't_3xp3c7_s3cur17y_2_LSFR}
Survey (survey)
アンケートに答えたら、フラグが表示された。
CakeCTF{w4s_th1s_CTF_p13c3_0f_c4k3_4U?}