神のミソ汁のセカイ

大学生活のことや技術的な備忘録を残してます

ASIS Cyber Security Contest 2015: simple Write-up

問題

ASIS Cyber Security Contest 2015: simple

チャレンジ中のリストはこちCrypto Challenges List(2015)

解法

問題ファイルはencryted_06bb0f5887231f735be0e2a21d68e79f。fileコマンドで調べるとxzファイルだったので解凍する。 中身は次のようなテキストファイルだった。

110d00_000a0701_1a00_00120812_171b1a171500111a150011_001b_071006001901_0900_787100_00091b00_00130805120f0908_0900_5143594353445602000105_140b0a000b_00021500151e141514_1b00_0a15000b0b0c0b02_1000131117_000f05_0a030000031b0908_001b_101f1c001a1d14_435340424400

16進数で表されたASCII文字列みたいだけど00とかが含まれている。英文が暗号化されているみたいだ。 _は暗号化されてないので単語間の区切りだと思われる。

「simple Cryptography」で調べると平文と鍵をXORする暗号化方式がヒットした。さらに調べると次のサイトにたどり着いた。

Pwn2Win CTF 2016 Simple Cryptography (Crypto 60) Writeup

別のCryptoの問題(しかも解いた問題より新しい)のWrite-upだが、暗号文が類似している。このサイトによると、_区切りの暗号文の各単語ごとに鍵(8bit)があり、その鍵を対応する単語に1文字ずつXORして暗号化する暗号方式のようだ。 この暗号方式だと踏んで鍵を探すプログラムを書いた。

# search_key.py
# -*- coding: utf-8 -*-
m = "110d00_000a0701_1a00_00120812_171b1a171500111a150011_001b_071006001901_0900_787100_00091b00_00130805120f0908_0900_5143594353445602000105_140b0a000b_00021500151e141514_1b00_0a15000b0b0c0b02_1000131117_000f05_0a030000031b0908_001b_101f1c001a1d14_435340424400"
m = m.split('_')
index = 0

for i in range(255):
    r = ''
    for j in range(0, len(m[index]), 2):
        d = int(m[index][j:j+2], 16)
        r += chr((d ^ i) % 256)

    print (str(i), ':', r)

このプログラムを実行すると意味のある英単語が出現した。方針は正しいみたい。 1単語ずつ復号し、実行結果を見ながら意味のある単語に復号される数字を記録していく。得られた鍵は

[101, 102, 115, 65, 116, 98, 117, 102, 53, 104, 102, 102, 48, 131, 112, 111, 101, 114, 97, 108, 98, 115, 33]

鍵がわかったので復号するプログラムを書いた。

# decrypt.py
# -*- coding: utf-8 -*-
m = "110d00_000a0701_1a00_00120812_171b1a171500111a150011_001b_071006001901_0900_787100_00091b00_00130805120f0908_0900_5143594353445602000105_140b0a000b_00021500151e141514_1b00_0a15000b0b0c0b02_1000131117_000f05_0a030000031b0908_001b_101f1c001a1d14_435340424400"
m = m.split('_')
key = [101, 102, 115, 97, 116, 98, 117, 102, 53, 104, 102, 102, 48, 131, 112, 111, 101, 114, 97, 108, 98, 115, 33]

r = ''
for i in range(len(m)):
    for j in range(0, len(m[i]), 2):
        d = int(m[i][j:j+2], 16)
        r += chr((d ^ key[i]) % 256)
    r += ' '

print ('decrypt message :', r)

実行結果

$ python3 decrypt.py
decrypt message : the flag is ASIS concatenate by result of MD5 hash function of asisctf2015 prepended to open
ning brace and followed by closing brace!

メッセージの通りasisctf2015MD5ハッシュ値を計算し、

$ md5 -s 'asisctf2015'
MD5 ("asisctf2015") = 7fc5bed10f3d903f1e69190a16562fcb

よってflagはASIS{7fc5bed10f3d903f1e69190a16562fcb}

まとめ

あのサイトにたどり着けたことが解答につながった。 ググってわかったがメッセージになんらかの鍵をXORする方法はよく用いられているみたいだ。

CTFよりも来週の暗号理論の期末テストの勉強しないと…