この大会は2018/10/27 15:00(JST)~2018/10/28 15:00(JST)に開催されました。
今回もチームで参戦。結果は 4245点で653チーム中7位でした。
自分で解けた問題をWriteupとして書いておきます。
mnemonic (Crypto)
$ cat mnemonic.txt { "japanese": [ [ "d3a02b9706507552f0e70709f1d4921275204365b4995feae1d949fb59c663cc", "ふじみ あさひ みのう いっち いがく とない はづき ますく いせえび たれんと おとしもの おどろかす ことし おくりがな ちょうし ちきゅう さんきゃく こんとん せつだん ちしき ぬいくぎ まんなか たんい そっと", "338c161dbdb47c570d5d75d5936e6a32178adde370b6774d40d97a51835d7fec88f859e0a6660891fc7758d451d744d5d3b1a1ebd1123e41d62d5a1550156b1f" ], [ "dfc9708ac4b4e7f67be6b8e33486482cb363e81967a1569c6fd888b088046f7c", "ほんやく ごうきゅう おさめる たこやき ごかん れいぎ やせる ふるい まんなか てんない だんろ さうな きぼう よくぼう しのぐ よけい こんき みうち らくご いわかん いこく あたためる のはら たぶん", "bdadda5bbff97eb4fda0f11c7141bc3ce3de0fef0b2e4c47900858cec639c10187aee4695b1ba462b1dd34b170b62801e68c270b93af62629f4964947a620ed9" ], [ "c0f...", "??? とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる", "e9a..." ], ], "flag": "SECCON{md5(c0f...)}" }
日本語の名称やタイトルで調べると、タイトル通り、mnemonicの問題。
日本語のリストは以下にあった。
https://github.com/bitcoin/bips/blob/master/bip-0039/japanese.txt
さらに何かよいライブラリがないか調べると、python-mnemonicがあったので、試しにこれを使ってみる。
https://github.com/trezor/python-mnemonic/tree/master/mnemonic
ここにもワードリストがある。試すときに、コード中の最後の方にある部分をenglishからjapaneseに変える。
m = Mnemonic('english') ↓ m = Mnemonic('japanese')
$ python mnemonic.py d3a02b9706507552f0e70709f1d4921275204365b4995feae1d949fb59c663cc ふじみ あさひ みのう いっち いがく とない はづき ますく いせえび たれんと おとしもの おどろかす ことし おくりがな ちょうし ちきゅう さんきゃく こんとん せつだん ちしき ぬいくぎ まんなか たんい そっと $ python mnemonic.py dfc9708ac4b4e7f67be6b8e33486482cb363e81967a1569c6fd888b088046f7c ほんやく ごうきゅう おさめる たこやき ごかん れいぎ やせる ふるい まんなか てんない だんろ さうな きぼう よくぼう しのぐ よけい こんき みうち らくご いわかん いこく あたためる のはら たぶん
問題の結果と一致する。この中のコードを見て、逆算する。ただし、1つ目のワードがわからないので、そこはブルートフォースする。
日本語の処理が面倒だったので、リストを見ながら、インデックス(何行目か)を抽出する。その結果を含めたコードは以下の通り。
#!/usr/bin/env python # -*- coding: utf-8 -*- import hashlib def decrypt(val): idxes = [val, 1333, 1376, 1953, 1173, 777, 570, 1262, 337, 1333, 995, 375, 1706, 616, 1485, 1404, 1495, 1644, 297, 91, 444, 1844, 2030, 24] b = '' for idx in idxes: b += bin(idx)[2:].zfill(11) b = b[:-8] data = '' for i in range(0, len(b), 8): data += chr(int(b[i:i+8], 2)) return data.encode('hex') pre = 'c0f' for i in range(2**11): h = decrypt(i) if h.startswith(pre): print 'val =', str(i) print 'h =', h break flag = 'SECCON{' + hashlib.md5(h).hexdigest() + '}' print flag
SECCON{cda2cb1742d1b6fc21d05c879c263eec}
でもよく考えたら、ブルートフォースする必要はなかった。11bitごとに最初の単語がきまるので、適当な単語で復号して、先頭3文字をc0fにするだけでよかった。