この大会は2017/11/17 21:00(JST)~2017/11/19 21:00(JST)に開催されました。
今回もチームで参戦。結果は959点で963チーム中24位でした。
自分で解けた問題をWriteupとして書いておきます。
helloworld (TRO 1)
$ nc 35.205.206.137 31337 hello? world hxp{w3lc0m3_70_7h3_hxpctf2017}
hxp{w3lc0m3_70_7h3_hxpctf2017}
ouchenticated (CRY 100)
概要は以下の通り。
平文:{"admin": 0}[MAC-KEY16バイト][本体28バイトのCRC] 暗号文が16進数で表示される。
{"admin": 1}でCRCも正しく計算して送信する必要がある。CTRモードなので、以下のような暗号イメージ。
[平文1ブロック目] ^ [鍵1] = [暗号1ブロック目] [平文2ブロック目] ^ [鍵2] = [暗号2ブロック目]
最初の1ブロック目は暗号1ブロック目の11文字目だけ、0でなく1になるようXORを計算するだけ。2ブロック目はCRCが入っていて、論理的には難しいので、いろいろテストしてみた。
その結果、暗号2ブロック目の最後の4バイトはadminの値が0のときと1のときとで、XORの値が固定('e1b652ef')であることがわかった。以上を踏まえてコードにすると、次のようになる。
#!/usr/bin/env python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('35.198.105.111', 32773)) b16_c = s.recv(1024).strip() print b16_c c = b16_c.decode('hex') c_ans = c[:10] c_ans += chr(ord(c[10]) ^ ord('0') ^ ord('1')) c_ans += c[11:28] # determined by test key = 'e1b652ef' b16_crc = '%x' % (int(c[28:].encode('hex'), 16) ^ int(key, 16)) c_ans += b16_crc.decode('hex') ans = c_ans.encode('hex') print ans s.sendall(ans + '\n') data = s.recv(1024) print data
hxp{CRC:_c0mpL3t3ly_r3duNd4nT_crYpT0gr4pH1c4LLy}