この大会は2022/12/10 20:00(JST)~2022/12/11 20:00(JST)に開催されました。
今回もチームで参戦。結果は1905点で251チーム中14位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome To BSides Mumbai CTF (Welcome)
問題にフラグが書いてあった。
BSMumbai{W3lcome_T0_BSides_Mumbai_CTF_2022}
Warmup (Reverse)
各インデックスでASCIIコードを比較している。
例えば、以下の場合、インデックス28で、55と比較している。
10: ; preds = %0 %11 = getelementptr inbounds [100 x i8], [100 x i8]* %2, i64 0, i64 28 %12 = load i8, i8* %11, align 4 %13 = sext i8 %12 to i32 %14 = icmp eq i32 %13, 55 br i1 %14, label %15, label %207
インデックスの位置に文字をセットして、順に並べればフラグになる。
>>> flag = [''] * 39 >>> flag[28] = chr(55) >>> flag[30] = chr(110) >>> flag[29] = chr(49) >>> flag[36] = chr(53) >>> flag[13] = chr(121) >>> flag[18] = chr(95) >>> flag[2] = chr(77) >>> flag[15] = chr(51) >>> flag[34] = chr(48) >>> flag[7] = chr(48) >>> flag[24] = chr(102) >>> flag[17] = chr(102) >>> flag[26] = chr(48) >>> flag[25] = chr(49) >>> flag[10] = chr(100) >>> flag[27] = chr(52) >>> flag[3] = chr(123) >>> flag[23] = chr(95) >>> flag[19] = chr(49) >>> flag[21] = chr(95) >>> flag[31] = chr(57) >>> flag[8] = chr(117) >>> flag[37] = chr(51) >>> flag[11] = chr(95) >>> flag[33] = chr(104) >>> flag[1] = chr(83) >>> flag[0] = chr(66) >>> flag[22] = chr(52) >>> flag[32] = chr(95) >>> flag[16] = chr(49) >>> flag[12] = chr(109) >>> flag[38] = chr(125) >>> flag[35] = chr(117) >>> flag[6] = chr(102) >>> flag[9] = chr(110) >>> flag[14] = chr(53) >>> flag[4] = chr(49) >>> flag[5] = chr(95) >>> flag[20] = chr(110) >>> ''.join(flag) 'BSM{1_f0und_my531f_1n_4_f10471n9_h0u53}'
BSM{1_f0und_my531f_1n_4_f10471n9_h0u53}
Poet Xor (Crypto)
8バイトXOR鍵の暗号。フラグが"BSMumbai"で始まり、最終行に記載されていると推測できることから鍵を求め、復号する。
#!/usr/bin/env python3 from itertools import cycle with open('flag.enc', 'rb') as f: cipher = f.read().splitlines() flag_head = b'BSMumbai' key = b'' last_line = bytes.fromhex(cipher[-1].decode()) for i in range(len(flag_head)): key += bytes([flag_head[i] ^ last_line[i]]) for h_ct in cipher: ct = bytes.fromhex(h_ct.decode()) msg = bytes([a ^ b for a, b in zip(ct, cycle(key))]).decode() print(msg)
メッセージの復号結果は以下の通り。
Two bits meet, each with its own One zero, one one, they are shown Together they combine, with a XOR A new value is formed, never a bore. BSMumbai{w0w_1t_1s_4_fl4g_1n_th3_3nd}
BSMumbai{w0w_1t_1s_4_fl4g_1n_th3_3nd}
Big RSA (Crypto)
eが大きいので、Wiener's Attackで復号する。
#!/usr/bin/env sage from Crypto.Util.number import * from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 def wiener(e, n): m = 12345 c = pow(m, e, n) q0 = 1 list1 = continued_fraction(Integer(e)/Integer(n)) conv = list1.convergents() for i in conv: k = i.numerator() q1 = i.denominator() for r in range(30): for s in range(30): d = r*q1 + s*q0 m1 = pow(c, d, n) if m1 == m: return d q0 = q1 return None with open('pubkey.pem', 'r') as f: pub_data = f.read() with open('flag.enc', 'r') as f: enc = bytes.fromhex(f.read()) pubkey = RSA.importKey(pub_data) n = pubkey.n e = pubkey.e d = int(wiener(e, n)) key = RSA.construct((n, e, d)) cipher_rsa = PKCS1_v1_5.new(key) from Crypto.Random import get_random_bytes sentinel = get_random_bytes(16) FLAG = cipher_rsa.decrypt(enc, sentinel).rstrip().decode() print(FLAG)
BSMumbai{RSA_with_bigE}
EggLamal (Crypto)
以下の式が与えられている。
g = 2 m = FLAG % p A = pow(g, a, p) B = pow(g, b, p) s = pow(A, b, p) c = s * m % p
ただし、p, A, B, c は既知、a, b は未知。B が p - 1 と同じ値になっているので、以下の式が成り立つ。
b = (p - 1) // 2
これでsの値が計算でき、それとcの値からmを計算し、フラグを求める。
#!/usr/bin/env python3 from Crypto.Util.number import * with open('params.txt', 'r') as f: params = f.read().splitlines() p = int(params[0].split(' ')[-1]) A = int(params[1].split(' ')[-1]) B = int(params[2].split(' ')[-1]) c = int(params[3].split(' ')[-1]) assert B == p - 1 g = 2 b = (p - 1) // 2 s = pow(A, b, p) m = (c * inverse(s, p)) % p FLAG = long_to_bytes(m).decode() print(FLAG)
BSMumbai{ElGamal_Publickey_Cryptography}