この大会は2021/3/13 5:00(JST)~2021/3/15 5:00(JST)に開催されました。
今回もチームで参戦。結果は1090点で3418チーム中937位でした。
自分で解けた問題をWriteupとして書いておきます。
esab64 (Warmups)
4バイトごとに逆にすれば、base64デコードできる。さらに3バイトごとに逆にして、パディングしている"_"を削除すると、フラグになった。
with open('esab64', 'r') as f: enc = f.read() b64 = '' for i in range(0, len(enc), 4): b64 += enc[i:i+4][::-1] dec = b64.decode('base64') flag = '' for i in range(0, len(dec), 3): flag += dec[i:i+3:][::-1] flag = flag.rstrip('_') print flag
flag{fb5211b498afe87b1bd0db601117e16e}
Buzz (Warmups)
$ file buzz buzz: compress'd data 16 bits $ mv buzz buzz.Z $ uncompress buzz.Z $ cat buzz flag{b3a33db7ba04c4c9052ea06d9ff17869}
flag{b3a33db7ba04c4c9052ea06d9ff17869}
Shoelaces (Warmups)
$ strings shoelaces.jpg | grep flag flag{137288e960a3ae9b148e8a7db16a69b0}
flag{137288e960a3ae9b148e8a7db16a69b0}
Pollex (Warmups)
$ file pollex pollex: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=5, description=Man giving thumb up on dark black background., software=Google], baseline, precision 8, 424x283, frames 3
https://www.dcode.fr/exif-thumbnailでサムネイルを抽出する。
flag{65c34a1ec121a286600ddd48fe36bc00}
Read The Rules (Warmups)
ルールのページのHTMLソースのコメントにフラグがあった。
<!-- Thank you for reading the rules! Your flag is: --> <!-- flag{90bc54705794a62015369fd8e86e557b} -->
flag{90bc54705794a62015369fd8e86e557b}
eaxy (Cryptography)
1つのkeyでXORをすると、数か所に以下の形式の文字列になる。
The XOR key you used to find string this is the [数値] character index of the flag :)
この文字列を表示したときのXOR鍵が復号文字で、数値がフラグ文字列のインデックスとなるようだ。これを元にフラグを構成する。
import re def decrypt(s, key): d = '' for c in s: d += chr(ord(c) ^ key) return d with open('eaxy', 'rb') as f: data = f.read() pattern = 'The XOR key you used to find string this is the (\d+) character index of the flag \:\)' flag = [''] * 38 for key in range(256): d = decrypt(data, key) for m in re.finditer(pattern, d): index = int(m.group(1)) flag[index] = chr(key) flag = ''.join(flag) print flag
flag{16edfce5c12443b61828af6cab90dc79}
Dice Roll (Cryptography)
サーバの処理概要は以下の通り。
■0. Info ・ランダム値は32bitであることを表示するだけ。 ■1. Shake the dice ・32ビットランダム整数をシード設定 ■2. Roll the dice (practice) ・32ビットランダム値表示 ■3. Guess the dice (test) ・32ビットランダム値を推測し、一致したらフラグが表示される。
Mersenne Twisterの問題そのもの。そのままスクリプトにして実行する。
import socket import random def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def untemper(rand): rand ^= rand >> 18; rand ^= (rand << 15) & 0xefc60000; a = rand ^ ((rand << 7) & 0x9d2c5680); b = rand ^ ((a << 7) & 0x9d2c5680); c = rand ^ ((b << 7) & 0x9d2c5680); d = rand ^ ((c << 7) & 0x9d2c5680); rand = rand ^ ((d << 7) & 0x9d2c5680); rand ^= ((rand ^ (rand >> 11)) >> 11); return rand s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('challenge.nahamcon.com', 31784)) data = recvuntil(s, 'L\n').rstrip() print data data = recvuntil(s, '> ') print data + '0' s.sendall('0\n') data = recvuntil(s, '\n').rstrip() print data data = recvuntil(s, '> ') print data + '1' s.sendall('1\n') data = recvuntil(s, '\n').rstrip() print data N = 624 state = [] for i in range(N): data = recvuntil(s, '> ') print data + '2' s.sendall('2\n') data = recvuntil(s, '\n').rstrip() print data data = recvuntil(s, '\n').rstrip() print data state.append(untemper(int(data))) state.append(N) random.setstate([3, tuple(state), None]) guess = str(random.getrandbits(32)) data = recvuntil(s, '> ') print data + '3' s.sendall('3\n') data = recvuntil(s, '> ') print data + guess s.sendall(guess + '\n') data = recvuntil(s, '\n').rstrip() print data data = recvuntil(s, '\n').rstrip() print data
実行結果は以下の通り。
_______ ______ | . . |\ / /\ | . |.\ / ' / \ | . . |.'| /_____/. . \ |_______|.'| \ . . \ / \ ' . \'| \ . . \ / \____'__\| \_____\/ D I C E R O L L 0. Info 1. Shake the dice 2. Roll the dice (practice) 3. Guess the dice (test) > 0 Our dice are loaded with a whopping 32 bits of randomness! 0. Info 1. Shake the dice 2. Roll the dice (practice) 3. Guess the dice (test) > 1 Shaking all the dice... 0. Info 1. Shake the dice 2. Roll the dice (practice) 3. Guess the dice (test) > 2 Rolling the dice... the sum was: 457371789 : 0. Info 1. Shake the dice 2. Roll the dice (practice) 3. Guess the dice (test) > 2 Rolling the dice... the sum was: 3422905258 0. Info 1. Shake the dice 2. Roll the dice (practice) 3. Guess the dice (test) > 3 Guess the dice roll to win a flag! What will the sum total be? > 2720670169 HOLY COW! YOU GUESSED IT RIGHT! Congratulations! Here is your flag: flag{e915b62b2195d76bfddaac0160ed3194}
flag{e915b62b2195d76bfddaac0160ed3194}