この大会は2020/2/24 2:00(JST)~2020/2/25 9:00(JST)に開催されました。
今回もチームで参戦。結果は1237点で175チーム中18位でした。
自分で解けた問題をWriteupとして書いておきます。
decrypto-1 (101, Crypto)
暗号はJSON形式のデータとのXOR(鍵は繰り返し)。
平文で分かっている部分から鍵を割り出して、復号する。
with open('flag.txt.enc', 'rb') as f: enc = f.read() pt_head = '{\n "filename": "' key = '' for i in range(len(pt_head)): code = ord(enc[i]) ^ ord(pt_head[i]) key += chr(code) print key key = key[:8] json_data = '' for i in range(len(enc)): code = ord(enc[i]) ^ ord(key[i%len(key)]) json_data += chr(code) print json_data
実行結果は以下の通り。
n0t4=l4gn0t4=l4gn0t { "filename": "flag.txt", "hash": "2f98b8afa014bf955533a3e72cee0417413ff744e25f2b5b5838f5741cd69547", "plaintext": "CTF{plz_dont_r0ll_ur_own_crypto}" }
CTF{plz_dont_r0ll_ur_own_crypto}
decrypto-2 (Crypto)
32バイトごとに以下のようにXOR鍵を生成し、暗号化する。
key = hashlib.sha256(指定key + struct.pack('<I', 0)).digest() key = hashlib.sha256(key + struct.pack('<I', 1)).digest() key = hashlib.sha256(key + struct.pack('<I', 2)).digest() :
平文で推定できる部分から最初の32バイトの鍵を割り出して、順に鍵を算出して復号する。
import hashlib import struct def str_xor(s1, s2): return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2)) with open('flag.svg.enc', 'rb') as f: enc = f.read() pt0 = '<?xml version="1.0" encoding="UT' key = str_xor(pt0, enc[:32]) flag = pt0 for i in range(32, len(enc), 32): e = enc[i:i+32] key = hashlib.sha256(key + struct.pack('<I', i // 32)).digest() pt = str_xor(key, e) flag += pt with open('flag.svg', 'wb') as f: f.write(flag)
復号したsvgをブラウザで確認すると、フラグが書かれていた。
CTF{but_even_I_couldnt_break_IT}
eccmul (101, Crypto)
$ nc eccmul-3e426cd0.challenges.bsidessf.net 25519 Elite | * . Crypto | * . Club | * . | **. | *R' | . *` | . * ` * | . ** ` * ** ** | . * ` ** ** . ** ` * | ** . ** ` ** | . *Q * ` * | . ` * .| ` * . | ` * . | ` ------------------------------.-----------------------------------`------------- * . | ` * . | ` * . | ` *. | ` . P* | * * ` . ** | * ** ` . *** ** * ` . * * * | * ` . | * ` . | ** ` | *` | `*R | * | * | * Curve Generated: y^2 = x^3 + 2363438179*x + 2897137567 mod 9111436894823654227 Point `P` on curve: [87547711026777508,898428857185524110] Scalar `s`: 7956552291 Please compute `R` = `s*P` R? (enter in form [1234,5678])>
ECCの掛け算ができればよい。
#!/usr/bin/env sage -python import socket def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('eccmul-3e426cd0.challenges.bsidessf.net', 25519)) data = recvuntil(sock, '> ') a = int(data.split('\n')[-6].split(' ')[6][:-2]) b = int(data.split('\n')[-6].split(' ')[8]) m = int(data.split('\n')[-6].split(' ')[10]) px = int(data.split('\n')[-5].split(' ')[4].split(',')[0][1:]) py = int(data.split('\n')[-5].split(' ')[4].split(',')[1][:-1]) s = int(data.split('\n')[-4].split(' ')[2]) F = FiniteField(m) E = EllipticCurve(F, [a, b]) P = E.point((px, py)) R = s * P ans = str([R[0], R[1]]) print data + ans sock.sendall(ans + '\n') data = recvuntil(sock, '\n').rstrip() print data data = recvuntil(sock, '\n').rstrip() print data
実行結果は以下の通り。
Elite | * . Crypto | * . Club | * . | **. | *R' | . *` | . * ` * | . ** ` * ** ** | . * ` ** ** . ** ` * | ** . ** ` ** | . *Q * ` * | . ` * .| ` * . | ` * . | ` ------------------------------.-----------------------------------`------------- * . | ` * . | ` * . | ` *. | ` . P* | * * ` . ** | * ** ` . *** ** * ` . * * * | * ` . | * ` . | ** ` | *` | `*R | * | * | * Curve Generated: y^2 = x^3 + 1210402129*x + 2262017573 mod 4175982898233455119 Point `P` on curve: [286697358245128449,392863369264505966] Scalar `s`: 6620774728 Please compute `R` = `s*P` R? (enter in form [1234,5678])> [1505341340027559791, 463288071213651829] Great! CTF{babys_first_scalar_multiplication}
CTF{babys_first_scalar_multiplication}