Meepwn CTF Quals 2018 Writeup

この大会は2018/7/14 4:00(JST)~2018/7/16 4:00(JST)に開催されました。
今回もチームで参戦。結果は940点で744チーム中61位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc)

問題にフラグが書いてある。

MeePwnCTF{welcome_to_meepwnctf_2018}

bazik (Crypto)

平文か以下の形式になっていることがわかっている。

Your OTP for transaction #731337 in ABCXYZ Bank is NNNNNNNNN.(NNNNNNNNN: 9桁の数字)

暗号が提示されるので、復号して9桁の数字を求める問題。平文の前半が分かっているので、Coppersmith's Attackで復号する。

$ nc 206.189.92.209 31333
	
Choose one:
1. Test the OTP
2. Get the public key
3. Get flag
2
-----BEGIN PUBLIC KEY-----
MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC0PgHUVlh3cH1QKTsyKBEHBoDC
LejSAfudEhJ7ITULJwWMAJ5nhYH3eHb24/oEnIPHtnjR3yHN8gR2JKs0KY6Oc3jt
Vt6U6abIdkDt5YpLTk6klFSUtpfUjuy2vtyKo3WS6i5Z7TBX2q8/gUtYohPAhW/c
BtP1PaC4Ml27a/fZdQIBAw==
-----END PUBLIC KEY-----
	
Choose one:
1. Test the OTP
2. Get the public key
3. Get flag
3
encrypted dat: 37d243fe30baea0ceaa207ccae44334ffacecf3697445c2853ba0db0a472f3005e0fc5ab7523d4537e7a20d3e944dde0c5d4e92653152d51cb9ee6a9b4a957c4a3568436ae4545eb6ecf7fd12465c476cb59375b9b7da887854b8de90228e48682b8eab0db668920544d2b5bfe453d7cb206f9a5c00aaf6d06345f9962544bf1
send me otp to get flag >>>

ここでまず公開鍵のパラメータを取り出す。

from Crypto.PublicKey import RSA

pub_data = '''-----BEGIN PUBLIC KEY-----
MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC0PgHUVlh3cH1QKTsyKBEHBoDC
LejSAfudEhJ7ITULJwWMAJ5nhYH3eHb24/oEnIPHtnjR3yHN8gR2JKs0KY6Oc3jt
Vt6U6abIdkDt5YpLTk6klFSUtpfUjuy2vtyKo3WS6i5Z7TBX2q8/gUtYohPAhW/c
BtP1PaC4Ml27a/fZdQIBAw==
-----END PUBLIC KEY-----
'''

pubkey = RSA.importKey(pub_data)
print 'n =', pubkey.n
print 'e =', pubkey.e

実行結果は以下の通り。

n = 126570387993773352057464496047518114039089955376411255273758820936424244005934231264031191100470471935989623362348875902002280486519035600680585067072794780485752362063129809129821906479269502815397703207234439049607596246154296610116751481620203765168805157880468117635796057965545347449889775012276948425077
e = 3

このパラメータを使って、暗号データを復号する。

# solve.sage
n = 126570387993773352057464496047518114039089955376411255273758820936424244005934231264031191100470471935989623362348875902002280486519035600680585067072794780485752362063129809129821906479269502815397703207234439049607596246154296610116751481620203765168805157880468117635796057965545347449889775012276948425077
e = 3
c = 0x37d243fe30baea0ceaa207ccae44334ffacecf3697445c2853ba0db0a472f3005e0fc5ab7523d4537e7a20d3e944dde0c5d4e92653152d51cb9ee6a9b4a957c4a3568436ae4545eb6ecf7fd12465c476cb59375b9b7da887854b8de90228e48682b8eab0db668920544d2b5bfe453d7cb206f9a5c00aaf6d06345f9962544bf1

beta = 1
epsilon = beta^2/7

nbits = n.nbits()
kbits = floor(nbits*(beta^2/e-epsilon))

msg = 'Your OTP for transaction #731337 in ABCXYZ Bank is XXXXXXXXXX'
msg = msg.replace('X', '\x00')
mbar = int(msg.encode('hex'), 16)

PR.<x> = PolynomialRing(Zmod(n))
f = (mbar + x)^e - c

x0 = f.small_roots(X=2^kbits, beta=1)[0]
real_msg = ('%x' % (mbar +x0)).decode('hex')
print real_msg

実行結果は以下の通り。

Your OTP for transaction #731337 in ABCXYZ Bank is 708540637.

得られたOTPを入力する。

send me otp to get flag >>> 708540637
MeePwnCTF{blackbox-rsa-is-0xd34d}
MeePwnCTF{blackbox-rsa-is-0xd34d}

esor (Crypto)

AES暗号CBCモードのivとkeyがわかっているので、暗号文を復号するだけ。

import socket
from Crypto.Cipher import AES

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('206.189.92.209', 12345))

data = s.recv(256)
data += s.recv(256)
print data + '1'
s.sendall('1\n')
data = s.recv(256)
print data + '1'
s.sendall('1\n')
data = s.recv(256)
print data + '1'
s.sendall('1\n')
data = s.recv(256)
print data

iv = data.decode('hex')[:16]
enc = data.decode('hex')[16:]

encrypt_key = '\xff' * 32
_aes = AES.new(encrypt_key, AES.MODE_CBC, iv)
print _aes.decrypt(enc)
MeePwnCTF{pooDL3-this-is-la-vie-en-rose-P00dle!}