この大会は2021/12/7 21:00(JST)~2021/12/19 21:00(JST)に開催されました。
今回もチームで参戦。結果は361点で103チーム中59位でした。
自分で解けた問題をWriteupとして書いておきます。
Grinch's Game (misc)
サーバの処理概要は以下の通り。
・r = random.Random(secrets.randbits(20)) ・my_number: 100未満のランダム整数 ・numbers_to_guess = 100 ・lives_remaining = 20 ・以下繰り返し ・answer: 整数入力 ・answerとmy_numberが一致している場合 ・numbers_to_guess: 1減算 ・my_number: 100未満のランダム整数 ・answerがmy_numberより小さい場合 ・"Too low..."と表示 ・lives_remaining: 1減算 ・answerがmy_numberより大きい場合 ・"Too high..."と表示 ・lives_remaining: 1減算 ・lives_remainingが0の場合、終了 ・numbers_to_guessが0の場合、フラグを表示
secrets.randbits(20)の部分(=secretとする)が20bitランダム整数で、これをブルートフォースして求める。このとき、secretを特定するのに必要なランダム整数の数は4つ。失敗回数が20のため、失敗する可能性があるが、成功するまで実行して4つの整数が入手できたら、次以降の整数を割り出すことができる。
#!/usr/bin/env python3 import socket import random def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('grinchgame.advent2021.overthewire.org', 1217)) data = recvuntil(s, b'...\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data) nums = [] for _ in range(4): g = [0, 99] while True: data = recvuntil(s, b'\n').rstrip() print(data) ans = (g[0] + g[1]) // 2 print(ans) s.sendall(str(ans).encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) if data == 'Correct!': nums.append(ans) break elif data == 'Too low...': g[0] = ans else: g[1] = ans for secret in range(2**20): r = random.Random(secret) found = True for i in range(4): my_number = r.randrange(100) if my_number != nums[i]: found = False break if found: break for _ in range(96): data = recvuntil(s, b'\n').rstrip() print(data) ans = r.randrange(100) print(ans) s.sendall(str(ans).encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data)
成功したときの実行結果は以下の通り。
SYSTEM INFO: CPython 3.10.1 (main, Dec 8 2021, 03:30:49) [GCC 10.2.1 20210110] on linux Are you feeling lucky? Let's play a game... [round 1/100] Guess my number: 49 Too low... [round 1/100] Guess my number: 74 Too high... [round 1/100] Guess my number: 61 Too high... [round 1/100] Guess my number: 55 Correct! [round 2/100] Guess my number: 49 Too low... [round 2/100] Guess my number: 74 Too high... [round 2/100] Guess my number: 61 Too low... [round 2/100] Guess my number: 67 Too high... [round 2/100] Guess my number: 64 Too low... [round 2/100] Guess my number: 65 Correct! [round 3/100] Guess my number: 49 Too low... [round 3/100] Guess my number: 74 Too high... [round 3/100] Guess my number: 61 Too low... [round 3/100] Guess my number: 67 Too high... [round 3/100] Guess my number: 64 Too high... [round 3/100] Guess my number: 62 Correct! [round 4/100] Guess my number: 49 Too low... [round 4/100] Guess my number: 74 Too high... [round 4/100] Guess my number: 61 Too high... [round 4/100] Guess my number: 55 Too high... [round 4/100] Guess my number: 52 Too low... [round 4/100] Guess my number: 53 Too low... [round 4/100] Guess my number: 54 Correct! [round 5/100] Guess my number: 68 Correct! [round 6/100] Guess my number: 20 Correct! [round 7/100] Guess my number: 42 Correct! [round 8/100] Guess my number: 28 Correct! [round 9/100] Guess my number: 85 Correct! [round 10/100] Guess my number: 58 Correct! : : [round 91/100] Guess my number: 71 Correct! [round 92/100] Guess my number: 95 Correct! [round 93/100] Guess my number: 74 Correct! [round 94/100] Guess my number: 73 Correct! [round 95/100] Guess my number: 71 Correct! [round 96/100] Guess my number: 94 Correct! [round 97/100] Guess my number: 33 Correct! [round 98/100] Guess my number: 60 Correct! [round 99/100] Guess my number: 18 Correct! [round 100/100] Guess my number: 41 Correct! YOU WIN! How are you so lucky!?!?? AOTW{wh3n_th3_0nly_w1nn1n6_m0ve_15_n0t_2_p14y}
AOTW{wh3n_th3_0nly_w1nn1n6_m0ve_15_n0t_2_p14y}