この大会は2018/5/19 10:00(JST)~2018/5/21 10:00(JST)に開催されました。
今回もチームで参戦。結果は5258点で400チーム中16位でした。
自分で解けた問題をWriteupとして書いておきます。
Number Game (Misc)
4つの数字を言うと、位置が合っている数と位置が違うが含まれている数を教えてもらい、正しい数字を推測するゲーム。Bulls and cows という名前らしい。
https://rosettacode.org/wiki/Bulls_and_cows/Player#Python を参考にコードを書く。チャンスは6回。
import socket import re import itertools import string import hashlib def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def parse_score(score): score = score.strip().split(',') return tuple(int(s.strip()) for s in score) def scorecalc(guess, chosen): bulls = cows = 0 for g,c in itertools.izip(guess, chosen): if g == c: bulls += 1 elif g in chosen: cows += 1 return bulls, cows s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('149.28.139.172', 10002)) data = recvuntil(s, '\n') print data pattern = 'sha256\(\*\*\*\*\+(.+)\) == (.+)' m = re.match(pattern, data) text_tail = m.group(1) h = m.group(2) data = recvuntil(s, ':') print data for c in itertools.product(string.digits + string.letters, repeat=4): text_head = ''.join(c) text = text_head + text_tail if hashlib.sha256(text).hexdigest() == h: print text_head s.sendall(text_head + '\n') break data = '' for i in range(17): data += recvuntil(s, '\n') print data digits = '0123456789' for round in range(8): choices = list(itertools.permutations(digits, 4)) answers = [] scores = [] data = '' for i in range(2): data += recvuntil(s, '\n') print data while True: ans = choices[0] answers.append(ans) dig_str = ' '.join(ans) print dig_str s.sendall(dig_str + '\n') data = recvuntil(s, '\n') print data if 'Nope.' in data: score = parse_score(data[6:]) scores.append(score) choices = [c for c in choices if scorecalc(c, ans) == score] else: break data = s.recv(1024) print data
失敗することも多々あるが、8ラウンド成功すればよいので、このコードで何回も挑戦。
RCTF{0lD_GaM3_nAmed_Bu11s_4nd_C0ws}
ECDH (Crypto)
$ nc ECDH.2018.teamrois.cn 42000 Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 1 Hello nobody...I'm Alice... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Bob's public key 4. tell me Bob's public key input here: 1 Bob sent me something.Bob said: Just kidding~ Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 1 Hello nobody...I'm Alice... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Bob's public key 4. tell me Bob's public key input here: 2 pub: 03474f81154bb8b931ddc36f9746484517 Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 1 Hello nobody...I'm Alice... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Bob's public key 4. tell me Bob's public key input here: 3 pub: 034320a6aeb0b093332d883a0c17fac4ce Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 1 Hello nobody...I'm Alice... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Bob's public key 4. tell me Bob's public key input here: 4 Alice have a new public key? Thank you for telling me! input here with hex string (e.g deadbeef): deadbeef Oops! Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 2 Hello nobody...I'm Bob... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Alice's public key 4. tell me Alice's public key input here: 1 I'v already told Alice...bye Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 2 Hello nobody...I'm Bob... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Alice's public key 4. tell me Alice's public key input here: 2 pub: 034320a6aeb0b093332d883a0c17fac4ce Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 2 Hello nobody...I'm Bob... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Alice's public key 4. tell me Alice's public key input here: 3 pub: 03474f81154bb8b931ddc36f9746484517 Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 2 Hello nobody...I'm Bob... you can: 1. ask for flag 2. ask me about my public key 3. ask me about Alice's public key 4. tell me Alice's public key input here: 4 Bob have a new public key? Thank you for telling me! input here with hex string (e.g deadbeef): deadbeef Oops! Welcome to my GETFLAG system 1. visit Alice 2. visit Bob 3. about input here: 3 ECDH.....https://github.com/esxgx/easy-ecc..secp128r1..AES...EBC.......
ECDHで共通鍵を渡し、AESのECBモードで暗号化したメッセージをBobが送っているということのようだ。
https://github.com/esxgx/easy-ecc ・public keyの2バイト目以降:l_public.x ・public keyの1バイト目:2 + (l_public.y[0] & 0x01)
上記の仕様に基づいているが、タイトル通りECDHの問題。
dA: Aliceの秘密鍵 dB: Bobの秘密鍵 QA: Aliceの公開鍵(QA = dA * G) QB: Bobの公開鍵(QB = dB * G) dA * QB = dA * (dB * G) = dB * (dA * G) = dB * QA
これが共通鍵になる。
Aliceの公開鍵をGにすると、dB * G、つまりBobの公開鍵が共通鍵となる。共通鍵を取得できたら、AESのECBモードで復号するとフラグが得られる。スクリプトにすると以下のようになる。
import socket from Crypto.Cipher import AES def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def send_data(s, data): r = recvuntil(s, ': ') print r + data s.sendall(data + '\n') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('ECDH.2018.teamrois.cn', 42000)) # Alice's public key setting send_data(s, '2') send_data(s, '4') send_data(s, '03161ff7528b899b2d0c28607ca52c5b86') # get Bob's public key send_data(s, '2') send_data(s, '2') r = recvuntil(s, '\n') print r[:-1] key = r[7:-1].decode('hex') # get encrypted flag send_data(s, '2') send_data(s, '1') send_data(s, '1') send_data(s, '1') r = recvuntil(s, '\n') print r[:-1] enc = r[32:-1].decode('hex') # decrypt aes = AES.new(key, AES.MODE_ECB) flag = aes.decrypt(enc) while True: if flag[-1] == '\x00': flag = flag[:-1] else: break print flag
RCTF{UgotTHEpoint}