SECCON 2018 Quals - mnemonic write up

次のようなJSONファイルが与えられる。日本語が並んでる文字列から上下のハッシュ値?みたいなのを求めると良いみたい。

{
    "japanese": [
    [
        "d3a02b9706507552f0e70709f1d4921275204365b4995feae1d949fb59c663cc",
        "ふじみ あさひ みのう いっち いがく とない はづき ますく いせえび たれんと おとしもの おどろかす ことし おくりがな ちょうし ちきゅう さんきゃく こんとん せつだん ちしき ぬいくぎ まんなか たんい そっと",
        "338c161dbdb47c570d5d75d5936e6a32178adde370b6774d40d97a51835d7fec88f859e0a6660891fc7758d451d744d5d3b1a1ebd1123e41d62d5a1550156b1f"
    ],
    [
        "dfc9708ac4b4e7f67be6b8e33486482cb363e81967a1569c6fd888b088046f7c",
        "ほんやく ごうきゅう おさめる たこやき ごかん れいぎ やせる ふるい まんなか てんない だんろ さうな きぼう よくぼう しのぐ よけい こんき みうち らくご いわかん いこく あたためる のはら たぶん",
        "bdadda5bbff97eb4fda0f11c7141bc3ce3de0fef0b2e4c47900858cec639c10187aee4695b1ba462b1dd34b170b62801e68c270b93af62629f4964947a620ed9"
    ],
    [
        "c0f...",
        "??? とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる",
        "e9a..."
    ],
    ],
    "flag": "SECCON{md5(c0f...)}"
}

Bitcoin の mnemonic

24単語が並ぶこれは、ビットコインの seed になる単語らしくて、BIP39 という規格のようだ。 日本語にも対応しており、まさに問題で与えられた日本語文字列みたいな感じだった。

使われる単語の一覧は全部で2048個らしくて、普通に公開されている

iancoleman.io

このサイトで変換ができ、例えばここに ふじみ あさひ... という文字列を入れると 338c161... の方の値が得られた!

f:id:castaneai:20181028153608p:plain

さらに、このサイトでいろいろポチポチしてると、Entropy という項目がでてきて、これが64文字の英数字だったので、近いと思ってここに d3a02b9... の値をいれてみたら見事にヒット!

f:id:castaneai:20181028153832p:plain

このテキストファイルの意味が判明する

テキストファイルの中身は

  • 1つめの英数字: Entropy
  • 2つめの日本語: BIP39 Mnemonic
  • 3つめの英数字: 上の BIP39 Mnemonic から生成された seed

ということがわかった。

あとは、テキストファイルの以下の謎の部分に当てはまるものを見つけたら、クリアということだ。

    [
        "c0f...",
        "??? とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる",
        "e9a..."
    ],

??? にあたる日本語を探す

??? はひとつだけなので、日本語を総当たりすればいけそう。Webツールだと総当たりなんてできないので、ここからは Python スクリプトにやらせることにした。

  • pip install mnemonic (Python 3 だと動かなかった (´・ω・`)、、なので Python 2 でやった)
  • 日本語全リストは Pythonのフォルダ/Lib/site-packages/mnemonic/wordlist/japanese.txt にある
# -*- coding: utf8 -*-
import mnemonic
import binascii

all_words = [w.strip() for w in open(r"C:\Python27\Lib\site-packages\mnemonic\wordlist\japanese.txt").readlines()]

for unknown in all_words:
    data = "{} とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる".format(unknown)
    words = [w.decode("utf8") for w in data.split(" ")]
    m = mnemonic.Mnemonic("japanese")
    seed = mnemonic.Mnemonic.to_seed(data)
    seed_hex = binascii.hexlify(seed)
    try:
        entropy_hex = binascii.hexlify(m.to_entropy(words))
        print(data)
        print(seed_hex)
        print(entropy_hex)
        print()
    except:
        pass

これを実行してしばらく待つと、こんな結果がでる

くろう とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる
9f5690af5e318d229f7e928c6a4f25e577e6c8ac1818930d1f4efdb6f8bef87f01f77336a54047b69f53ce15a7837241b71ff13714e383aa6e63d71f0e0162b6
3f54d6b07a192ac251d4ee2a34d5f1977d549a2e6d7cbaf9b09485b379cd3f70
()
けんこう とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる
29113d4a66981f5c465ff6cfb09be838ef4b511840250ddad034b3ddb51e8825bc8bc4d0bdb639294f95d2b361f225b0f3fb4897216fb3ef00f319669370cdec
48b4d6b07a192ac251d4ee2a34d5f1977d549a2e6d7cbaf9b09485b379cd3f70
()
だいどころ とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる
40c57e082f41ec75fcd7f22f597643eed8c8d2e76a32dd30d3a498257daf4a7a351bdabc3adaf6264ee4cfdeeb14bbe01a2115d1b2b54419b711c6bd4ec656c9
85d4d6b07a192ac251d4ee2a34d5f1977d549a2e6d7cbaf9b09485b379cd3f70
()
はいれつ とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる
e9a4cc18d3db07dc5e575e6d8bba54a69cd60b092cbaecd5f3aa5fec40324e0f1be65be20442dade5f2a58eac91e46b9cbbcec08fce949b8fd8e30aed1e06d1a
c0f4d6b07a192ac251d4ee2a34d5f1977d549a2e6d7cbaf9b09485b379cd3f70
()
りねん とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる
9c984ad3c64fc0c95ad4684da932677342245d681a6cf069e165882f280437ca6337a760bd3d581095dc726b6f865ecb5a91f438040c05966cc8af89a51b15fd
f8d4d6b07a192ac251d4ee2a34d5f1977d549a2e6d7cbaf9b09485b379cd3f70
()

この中で、Entropy が c0f... で始まるのは はいれつ ... から始まるやつなので、これを md5 かけて、クリア!

$ echo -n c0f4d6b07a192ac251d4ee2a34d5f1977d549a2e6d7cbaf9b09485b379cd3f70 | md5sum
cda2cb1742d1b6fc21d05c879c263eec
SECCON{cda2cb1742d1b6fc21d05c879c263eec}