ChogeLog

主にセキュリティ関係の記録やWrite-up。たまーに日記も。

VoIP (Forensics, 100)

SECCON2016 Online CTF の VoIP

問題

pcapファイルが与えられます。
フラグ形式は SECCON{[A-Z0-9]} となっています。


pcapファイルだから、とりあえずWiresharkで開いてみる。
f:id:swime:20161214210257j:plain

普段の研究ではWiresharkを使ってHTTP通信の解析なんかをやってるんだけど、見慣れないRTPプロトコルが使われている。
問題名からしてVoIPに関するパケットなんだろうなぁーと思いながらRTPプロトコルググると、やっぱりVoIPで使われるプロトコルみたい。
あ、ちなみにVoIPとは、インターネットとかのネットワーク上で、パケット化した音声データを受け渡しすることで音声通話を実現している技術のことです(院の講義で習った)。いわゆるIP電話というもので、Skypeとかで使われてる技術ですねー

とりあえず音声を聞きたいので、「電話」⇒「RTP」⇒「ストリーム分析」⇒「ストリームを再生」
f:id:swime:20161214212312j:plain

それっぽい波形を確認できたので、実際に音声を再生して聞いてみると…
英語で何やら喋っていて、前半は全く何を言っているのか分からなかったけど、後半に「flag is…」っていうのが聞こえたから音声で答えを言ってるっぽい。
音声データをファイルとして保存して、Windows Media Playerで頑張って聞いてみると…

SECCON{9001IVR}と言っていてフラグゲット!

この音声を聞き取る作業にはかなり苦労した…(笑)
記号の「{」や「}」を英語で何て言うのか知らなかったし、「V」と「B」のどっちか分からなかったし…(最初はVをBだと思って答えた 笑)

それにしてもWiresharkは便利すぎて恐ろしい…(悪用厳禁!!)

Vigenere (Crypto, 100)

SECCON2016 Online CTF の Vigenere

ヴィジュネル暗号を解読する問題
暗号についてはWikipediaで見てください!
この暗号は見たことある気がするけど、暗号名を知ったのは初めてかも。。笑

問題

鍵: ????????????
平文: SECCON{???????????????????????????????????}
暗号: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ
使われている文字列:ABCDEFGHIJKLMNOPQRSTUVWXYZ{}

それと、答えとなる平文のハッシュ値が与えられている。


要は、暗号文と少しの平文から鍵を予測して、その鍵を使って暗号文を平文に復号してくださいっていう問題ですね。
ヴィジュネル暗号は「鍵」「平文」「暗号文」のうち二つの情報を知っていれば、残り一つの値を導くことができます。最初に平文は7文字まで分かっているので、鍵も7文字だけ分かり、「VIGENER」という文字列が出てきます。8文字目は「E」になるかな?と予想はできるのですが、それ以降の鍵を予想するのは難しいですよね…
ということで、あとは総当たりによって鍵を導き出すプログラムを作ってみます。

自分はJavaが得意なのですが、あえて勉強中のPythonで組みました!

# coding:utf-8

import sys
import hashlib

# 引数:読み込みファイル名
input = sys.argv
file_name = str(input[1])
key_string = "VIGENERAAAAA"

# ファイル読み込み
file = open(file_name, 'rt')
text = file.read()
string_list = list(text)

# キーを総当たりでチェック
for a in range(65, 91):
    key_string = key_string[0:7]
    key_string += chr(a)
    for b in range(65, 91):
        key_string = key_string[0:8]
        key_string += chr(b)
        for c in range(65, 91):
            key_string = key_string[0:9]
            key_string += chr(c)
            for d in range(65, 91):
                key_string = key_string[0:10]
                key_string += chr(d)
                for e in range(65, 91):
                    key_string = key_string[0:11]
                    key_string += chr(e)

                    # メイン処理
                    count = 0
                    new_string = ""
                    for string in string_list:
                        ascii = ord(string[0])
                        new_ascii = ""
                        key_number = count % len(key_string)
                        key_ascii = ord(key_string[key_number])

                        if key_ascii == 123:
                            key_ascii = 27
                        elif key_ascii == 125:
                            key_ascii = 28
                        else:
                            key_ascii -= 64

                        # 大文字
                        if 64 < ascii < 91:
                            new_ascii = (ascii - 64) - key_ascii
                            if new_ascii < 0:
                                 new_ascii += 28
                            new_ascii += 65

                        # {
                        elif ascii == 123:
                            new_ascii = 27 - key_ascii
                            if new_ascii < 0:
                                new_ascii += 28
                            new_ascii += 65

                        # }
                        elif ascii == 125:
                            new_ascii = 28 - key_ascii
                            if new_ascii < 0:
                                new_ascii += 28
                            new_ascii += 65

                        # 文字コードが91なら { に変換
                        if new_ascii == 91:
                            new_ascii = 123

                        # 文字コードが92なら } に変換
                        if new_ascii == 92:
                            new_ascii = 125

                        new_string += chr(new_ascii)
                        count += 1

                    # ハッシュ処理
                    check = hashlib.md5(new_string.encode()).hexdigest()
                    check2 = "f528a6ab914c1ecf856a1d93103948fe"
                    if check == check2:
                        print("KEY is " + key_string)
                        print(new_string)
                        break

print("Not found!!")

初心者だと丸わかりのコードですね…
鍵を見つけても実行停止しないという( ;∀;)笑
まぁ答えさえ分ればいいので、その辺りは置いといて…

処理の流れとしては…
総当たりで鍵を作る ⇒ その鍵を使って暗号文を平文に復号 ⇒ 平文のハッシュ値を生成して、答えのハッシュ値と比較 ⇒ 一致すれば答えを出力

ちなみに、

平文 = 暗号文 - 鍵

の関係を用いて計算しています。

このプログラムを実行して数分待つと…
f:id:swime:20161214205012j:plain
フラグゲットです!

下手なコードでスミマセン…少しずつPython勉強していきます。。

#2 Easy Cipher

はてなブログデビュー!

今までは他のブログサービスを使ってたのですが、コードも書いた方がいいなぁーと思って、コードが見やすい?はてなブログを始めました(。・ω・)ノ゙

初投稿はテストも兼ねて、前のブログに書いてた内容を書きます。

======================================================

ksnctfの2問目
http://ksnctf.sweetduet.info/problem/2

知ってる人は見た瞬間に分かると思うけど、シーザー暗号を解読する問題(-ω-)

で、問題になるのは何文字シフトすればいいか。

コツとしては、1文字~3文字で出現頻度の多い文字列を探す。

この問題だと、「vf」が多く使われていることが分かる。

ここで、一般的に英語の文章では、「a」、「is」、「the」などの単語が多く使われているので、「vf」は「is」に置換できるんじゃないかと予想する。

シフト数を計算してみると・・・

v → i は13文字

f → s も13文字

さらに、一文字で多く出現している「n」を13文字ずらすと「a」になる。


以上のことから、この問題はROT13であると予想できる。

あとはネット上でROT13を計算できるサイトを探して復号すれば解ける!


せっかくなので、自分は勉強中のPythonで復号プログラムを組んでみた。

# coding:utf-8

import sys

# 引数:読み込みファイル名、シフト数
input = sys.argv
file_name = str(input[1])
no = int(input[2])
plain_text = ""

# ファイル読み込み
file = open(file_name, 'rt')
text = file.read()
string_list = list(text)

for string in string_list:
    ascii = ord(string[0])
    new_ascii = ""

    # 大文字
    if 64 < ascii < 91:
        new_ascii = (ascii - 65 + no) % 26 + 65

    # 小文字
    elif 96 < ascii < 123:
        new_ascii = (ascii - 97 + no) % 26 + 97

    # それ以外
    else:
        new_ascii = ascii

    plain_text += chr(new_ascii)

print(plain_text)

Pythonの勉強始めたばかりだから大目に見てね。。。

で、出力結果↓↓

“ROT XIII is a simple letter substitution cipher that replaces a letter with the letter XIII letters after it in the alphabet. ROT XIII is an example of the Caesar cipher, developed in ancient Rome. Flag is FLAGSwagxBJSAMqwxxAU. Insert an underscore immediately after FLAG.”

FLAGの後にアンダースコアを入れるとフラグをゲット!

======================================================


自分が書いたコードを公開するのって物凄く恥ずかしい。。。笑