nullcom HackIM 2018 Writeup

この大会は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'}