この大会は2018/2/10 7:00(JST)~2018/2/11 15:00(JST)に開催されました。
今回もチームで参戦。結果は700点で248チーム中76位でした。
自分で解けた問題をWriteupとして書いておきます。
What did he said? (Crypto 300)
暗号ファイルと、2つの公開鍵recovered_1.keyとrecovered_2.keyが与えられている。この公開鍵のn, eの値を確認する。
from Crypto.PublicKey import RSA with open('What_did_he_said\\recovered_1.key', 'r') as f: pub_data1 = f.read() with open('What_did_he_said\\recovered_2.key', 'r') as f: pub_data2 = f.read() pubkey1 = RSA.importKey(pub_data1) print pubkey1.n print pubkey1.e pubkey2 = RSA.importKey(pub_data2) print pubkey2.n print pubkey2.e
この結果は以下の通り。
[recovered_1.key] 267655291201323217581766648921840701061 65537 [recovered_2.key] 307896566740839738127153373769666872203 65537
factordbで素因数分解する。
267655291201323217581766648921840701061 = 14673311234908966559 * 18240960538242393179 307896566740839738127153373769666872203 = 16879405341365159057 * 18240960538242393179
どちらかの鍵で復号できるはず。
with open('What_did_he_said\\encrypt.txt', 'rb') as f: c = int(f.read().encode('hex'), 16) p = 16879405341365159057 q = 18240960538242393179 n = p * q e = 65537 a = (p - 1) * (q - 1) x = 0 while True: if (a * x + 1) % e == 0: d = (a * x + 1) / e break x = x + 1 m = pow(c, d, n) flag = ('%x' % m).decode('hex') print flag
結果2つ目の鍵で復号できた。
BabaSaidJaiJugad
hackim18{'BabaSaidJaiJugad'}
Jailbreak (Crypto 200)
CBCモードなので、以下のようになる。
[平文1ブロック目] ^ IV --(暗号化)--> [暗号文1ブロック目] [平文2ブロック目] ^ [暗号文1ブロック目] --(暗号化)--> [暗号文2ブロック目] [平文3ブロック目] ^ [暗号文2ブロック目] --(暗号化)--> [暗号文3ブロック目]
鍵を調整しながら、後ろのブロックから復号していく。IVの前半7バイトがID+IDの形式の16進表記として、ブルートフォースで名前が小文字のASCIIコードのみで復号できるものを洗い出す。
from hashlib import md5 from Crypto.Cipher import AES import string def unpad(s): return s[0:-ord(s[-1])] def str_xor(s1, s2): return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(s1, s2)) def chk_name(s): for i in range(len(s)): if s[i] not in string.lowercase: return False return True encoded = 'U2FsdGVkX1+1KcLc+WlP8rcjdSP8DnOx/W1h+lww6rGCUVH4ghAuhSs+Xs9ShwJNEFlJ4IWDoG00T4LnAqIMrsY9EODHGc7Jv/Rn1lC/h7k=' encrypted = encoded.decode('base64') salt = encrypted[8:16] secret = 'jailbreak123' key = md5(secret + salt).digest() cipher = encrypted[16:] aes = AES.new(key, AES.MODE_ECB) xor4 = aes.decrypt(cipher[48:64]) plain4 = str_xor(xor4, cipher[32:48]) plain4 = unpad(plain4) xor3 = aes.decrypt(cipher[32:48]) plain3 = str_xor(xor3, cipher[16:32]) xor2 = aes.decrypt(cipher[16:32]) plain2 = str_xor(xor2, cipher[:16]) xor1 = aes.decrypt(cipher[:16]) print xor1 + plain2 + plain3 + plain4 for i in range(10000000): id = '%07d' % i iv = id + id name = str_xor(iv.decode('hex'), xor1[:7]) if chk_name(name): print id print name
以下上記コードの実行結果で、復号の途中と、IDと名前の組み合わせ。
1uwK;prison_term=3yrs;about=speaker at nullcon 2018; 8060624 spmysqo 8060625 spmisqn 8061624 sqmysao 8061625 sqmisan 8071624 samyrao 8071625 samiran 8160624 rpmycqo 8160625 rpmicqn 8161624 rqmycao 8161625 rqmican 8171624 ramybao 8171625 ramiban 9060624 cpmxsqo 9060625 cpmhsqn 9061624 cqmxsao 9061625 cqmhsan 9071624 camxrao 9071625 camhran 9160624 bpmxcqo 9160625 bpmhcqn 9161624 bqmxcao 9161625 bqmhcan 9171624 bamxbao 9171625 bamhban
nullcon 2018のスピーカーということで、https://nullcon.net/website/goa-2018/about-speakers.phpを調べると、SAMIRAN GHATAKという人がいる。
hackim18{'8071625'}