暗号を解いて遊ぼう、CTF(capture the flag)やってみた。ctfとは?初心者入門や勉強方法。

暗号を解いて遊ぼう、CTF(capture the flag)やってみた。ctfとは?初心者入門や勉強方法。

会社の知り合いがCTF(capture the flag)を勧めてくれたのでやってみた。
ゲーム感覚でプログラミングやセキュリティを学ぶことが出来るので、継続して記事にまとめていきたい。
まずCTFとは何か、そして入門サイトや勉強方法、一部の問題の解き方などをまとめる。

CTF(Capture the flag)とは?

CTFとは、Capture the flagと呼ばれるセキュリティコンテストの一つ。
和訳すると、「旗を捕まえろ」で、その名前の通り、セキュリティの穴を見つけて旗=フラグを見つけることが目的になる。
ジャンルは多岐にわたり、WebのいわゆるSQLインジェクション(入力フォームなどにSQL文を打ち込む)を使うことや、
ある文章をあたえられて、そこから暗号文を解読するようなものまでより取り見取りである。

暗号文の例

seasor_ango
非常にわかりやすい画像

上の文章だけだとよくわからないと思うので、暗号解読の例を出してみる。
今回は「シーザー暗号」と呼ばれる、あのローマ帝国のユリウス・カエサルが使っていたとされる暗号を使う。
その内容は至って単純で、「原文をアルファベットを〇文字ずらした文章を作る」というもの。
例えば、「I like aisya. 」という暗号があった場合、シーザー暗号で1文字前にずらすと、
「h khjd zhrxz」という意味不明の文章になり、暗号化完了というわけである。

CTFでは、この「h mhjc zhrxz」という文章が与えられ、これが何を意味するか答えたり、
元の文章を復元することが目標となる。

入門サイト

今回知り合いから紹介されたのは以下のサイト。
CpawCTF
競プロと似ているUIなので、すぐに登録してチャレンジできる。
AtCorderなどと違うのは、毎週コンテストがある形ではなく、いつでも挑戦してレベルアップを目指せる点だろう。
時間があるときなら何時でも出来るので、隙間時間に勉強できるのが良い。

早速レベル1をやってみたので、試しに2問(というか1問)解説していく。

Q1.[Misc] Test Problem

こぴーあんどぺーすと!

Q2.[Crypto] Classical Cipher

seasor_ango
非常にわかりやすい画像

最初に例に出したシーザー暗号
アルファベットをずらすだけで、文字数も指定されているので後はずらすコードを書くだけ。
(頑張って手動で復元してもいいが・・・)

今回はshell芸で解いてみた。
答えの核心を書くのはNGなので、あくまで解説のみ。

まずはアルファベットをずらすコードはこうなる。

echo "h khjd zhrxz" | tr $(printf %1s | tr ' ' '.')\a-z a-za-z

詳しく分解していく。
まず、

echo “h khjd zhrxz”

この部分は、echoコマンドで暗号文を出力しているだけ。

続いてやや複雑なこの部分。

tr $(printf %1s | tr ‘ ‘ ‘.’)\a-z a-za-z

trコマンドは、tr A B で、ABに置き換えるということが出来るもの。
なので、
tr $(printf %1s | tr ‘ ‘ ‘.’ )\a-z a-za-z
という区切りになるので、$()で囲まれた以下のprintf部分を解説していく。

$(printf %1s | tr ‘ ‘ ‘.’ )\a-z
まず、$()は、内側にあるコマンドを先に実行した結果を出力してコマンドラインに組み込むことが出来る。
続いて$()の中。printfコマンドは、0埋めなど、文字のフォーマットを指定して、その通りに出力することが出来るコマンド。
今回だと、printf %Nsで、N埋めの空白で埋めた文字列を出力することが出来る
例えば以下のコマンドを入力した結果は、

$ printf %2s "a"
# a

となり、空白が一個前についている。
なので、今回はずらす数の分だけ、暗号文の前に空白を入れている
そして、空白を全てtrコマンドを使ってドットに置換する。
先ほどのコマンドを読みやすくすると、以下のような状態になっている。

 echo "h khjd zhrxz" | tr .\a-z a-za-z

最後にこちらのtrコマンド

tr .\a-z a-za-z

こちらを解説する前に以下のコマンドとその実行結果を見てもらいたい。

$ echo abcabc | tr abcdefg bcdefgh
#bcdbcd

このコマンドはどういうことかというと、
trは複数文字のSETがある場合、同じ列数の場所にある単語へと置換されるということである。
(よく使うtr a-z A-Zで小文字大文字置換が出来るのもそういう訳である。)
ここで先ほどのコマンドに戻ると、

tr .\a-z a-za-z

とすることで、a-zの対応が一文字ずつずれることがわかる。
要するに、こういう状態になる。

tr .abcdefg(省略)xyz abcdefg(省略)xyz

※z後ろがa-zで二つになっているのは、最初に渡した文字をずらした際にzを超えた時のため。

これで、N文字ずれたシーザー暗号を解読することができた。
printf %NsのNをいじれば何文字でも対応できる(26文字を超えると追加のa-zが必要になるが)

まとめ

というわけで、長々と解説したが以上のような方法で問題を解いて楽しむのがCTFである。
勉強方法としては、暗号解読については暗号そのものがどういう仕組みなのかを勉強すること。
そしてその仕組みをどうすれば機械的に解読できるか考えることが必要となってくる。

Webについては、いくつか代表的な攻撃があるので、それらを覚えておくのが良いだろう。
とはいえ、セキュリティの範囲は多岐にわたるので、無理に一気に勉強しようとするより、
上記のサイトを使って一問ずつ進めつつ、わからなくなったら適宜調べるというのがよさそうだ。

是非いろんな人が参加してくれると嬉しい。