この大会は2016/10/8 3:00(JST)~2016/10/9 21:00(JST)に開催されました。
今回もチームで参戦。結果は44点で776チーム中53位でした。
自分で解けた問題をWriteupとして書いておきます。
rollthedice (crypto)
Go言語のスクリプトが添付されている。概要は以下の通り。
・16バイトのキーで16バイトのメッセージがAES暗号化されて提示される。
・提示されたメッセージの平文の最初の16ビットは1~6の数を表している。
・こちらも同様に暗号化メッセージとキーを提示する。
・こちらの提示したものが表す数と上記の数の合計が7になるように提示する必要がある。
上記の条件を満たすようにメッセージを固定し、キーを変えて、条件をみたすようにブルートフォースで答えていく。スクリプトは以下の通り。
#!/usr/bin/env python import socket import re import struct import string import itertools from Crypto.Cipher import AES def recvuntil(s, tails): data = "" while True: for tail in tails: if tail in data: return data data += s.recv(1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('challenges.hackover.h4q.it', 1415)) data = recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') data += recvuntil(s, '\n') print data for i in range(32): print 'Round %d' % (i + 1) data = recvuntil(s, '\n') print data pattern = 'My dice roll: (.+)\n' m = re.search(pattern, data) my_dice_roll_enc_b64 = m.group(1) data = recvuntil(s, ':') data += recvuntil(s, ' ') your_dice_roll_enc = 'AAAAAAAAAAAAAAAA' your_dice_roll_enc_b64 = your_dice_roll_enc.encode('base64') data += your_dice_roll_enc_b64 print data s.sendall(your_dice_roll_enc_b64) data = recvuntil(s, '\n') print data pattern = 'My key: (.+)\n' m = re.search(pattern, data) my_key_b64 = m.group(1) data = recvuntil(s, ':') data += recvuntil(s, ' ') my_key = my_key_b64.decode('base64') aes1 = AES.new(my_key) my_dice_roll_enc = my_dice_roll_enc_b64.decode('base64') my_dice_roll = int(aes1.decrypt(my_dice_roll_enc).encode('hex')[0:4]) expected = 7 - my_dice_roll for c in itertools.combinations_with_replacement(string.printable, 4): your_key_tail = ''.join(c) your_key = 'AAAAAAAAAAAA' + your_key_tail aes2 = AES.new(your_key) h = aes2.decrypt(your_dice_roll_enc).encode('hex') if h[0:4] == '000' + str(expected): break your_key_b64 = your_key.encode('base64') data += your_key_b64 print data s.sendall(your_key_b64) data = recvuntil(s, '\n') print data
実行すると、32ラウンドの後、フラグが表示された。
: Round 32 My dice roll: asCvL0SUQrfvrQQ0VK18pA== Your dice roll: QUFBQUFBQUFBQUFBQUFBQQ== My key: gNflaEQwFBcSGPJgeerGrw== Your key: QUFBQUFBQUFBQUFBMGJrLg== You win! How was that possible? However, here is your flag: hackover16{HowAboutAuthenticatedEncrYption?}
hackover16{HowAboutAuthenticatedEncrYption?}