CTF 入門にあたってセキュリティ初心者が色々調べてみた

CTF

なぜ CTF をやろうと思ったか

「ハッキング・ラボのつくりかた」を一周したので、セキュリティに関する勉強をどうやって進めようか考えていました。

セキュリティ知識を向上させたい
→知識を身につけるには実践的な技術、経験が必要
→業務以外の時間でもスキルを磨くには?
→CTF というセキュリティコンテストがあるらしい
→ただ教科書を読むのではなく、ゲーム感覚で楽しめるらしい
→やってみよう!

ということで、CTF にチャレンジします。

この記事は、以下のような方(セキュリティ初心者)を対象としています。
・これから CTF を始めようと思ってる方
・ CTF って聞いたことがあるけどよくわからない方

問題を解く前に前提知識としてこれが必要!と言われても入ってこないので、まずはこの記事でイメージを掴んでもらえたらと思います。
必要となる知識は、問題を解きながら別記事で解説したいと思っています。

CTF ってなんだろう

Capture The Flag の略のようです。
Google 翻訳すると「旗を取れ」です。どういうことでしょう?

Wikipediaでは、以下のように記載されています。

コンピュータセキュリティの分野におけるキャプチャー・ザ・フラッグ(CTF)は、コンピュータセキュリティ技術の競技である。CTFは通常、参加者に対しコンピュータを守る経験に加え、現実の世界で発見されたサイバー攻撃への対処を学ぶ教育手法として企画されている。「ハッカーコンテスト」[1]「ハッキング大会」[2]「ハッキング技術コンテスト」[3]「ハッカー大会」などとも訳される。

Wikipedia

簡単に言うと、ハッカーの大会だそうです。これで結果を残そうと頑張るうちにセキュリティ知識が身についていくわけですね。

世界各地で開催されており、日本では「SECURITY CONTEST (SECCON)」という大会が開催されています。

※注意※
CTF の感覚で一般のサイトやシステムに攻撃を行うのは犯罪行為になる可能性があります。必ず CTF として公開されているサーバでルールを守って楽しみましょう。

どんな大会?

ハッカーの大会と言ってもどんなことを競技としているのでしょうか?

CTF は通常、「クイズ形式」「攻防戦形式」「King of the hill 形式」のいずれかで行われます。

全員で同じ問題を解く「クイズ形式」と、チーム同士が対決する「攻防戦形式」「King of the hill 形式」に大別され、予選で「クイズ形式」が用いられ、その後トーナメント形式で「攻防戦形式」「King of the hill 形式」が用いられることが多いようです。

スポンサーには有名な大企業が名を連ねており、国際大会で優勝したチームにはなんと経済産業大臣賞が授与されるとのことです。
このことからも、結果を残せば人生が変わるような大会だと考えられます。芸人でいうM-1みたいなものですかね。夢のある大会ですね。

本記事では、気軽に参加可能な「クイズ形式」に焦点を当てて記事を書いていきます。

クイズ形式ではどんな問題が出題される?

全員が同じ問題を解くクイズ形式。
入門者が初めに CTF に触れるのがクイズ形式になるかと思います。

クイズ形式では、問題に隠された Flag と呼ばれるデータを探し当てればポイントとなります。
そのポイントが高ければ勝利というのが基本的なルールです。

クイズ形式で代表的なルールは以下の6種です。

・Reversing (Binary)
・Forensics
・Pwnable(Pwn)
・Web
・Network
・Cryptography (Crypto)

この単語からではどんな問題が出題されるか全く想像できません。
それぞれ説明していきます。

Reversing (Binary)

リバースエンジニアリング、バイナリ解析のことを指します。

リバースエンジニアリングとは、ソフトウェアで言うと実行ファイル等を分析することで公開されていない仕様や動作を特定する行為です。
この解析に「バイナリ解析」が用いられます。

バイナリって?

バイナリ解析を説明する前に、バイナリとは何かを説明します。
まずバイナリとは、コンピュータが理解できる形式のデータのことです。慣用的にはテキストデータ以外のデータを指しますが、CTF ではより狭義的に「実行可能な形式のデータファイル」を指すようです。

バイナリをイメージしやすいように、実際に適当に作成したファイルをバイナリエディタで開いてみます。バイナリエディタは「Stirling」を使用します。

以下のテキストファイルをバイナリエディタで起動したいと思います。

「Stirling」を起動し、「ファイル > 開く」から上記のファイルを開きます。すると、以下のようにバイナリデータの形式で表示されます。

このような数字が並んだデータがバイナリデータと理解してもらえれば大丈夫です。CTF では実行形式のファイルを解析するのでこんな小さいデータではないですが。。

解析ってどういうこと?

さて、上記のようなデータを解析すると言ってもイメージしづらいと思います。

まず目的としては、先述した通りどんな動きをするかを特定することです。
実行形式のプログラムなので、実行すれば挙動を見れるのですが一部の入出力の結果しか得られず、そのプログラムがどういう動きをし得るのかといったことまではわかりません。

例えば「CTF」という文字列を入力すれば「正解」と出力され、その他文字列を入力すると「不正解」と出力されるプログラムがあるとします。
これをポンと渡され実行してみても、当然「CTF」と入力する可能性はゼロに近く、ただ「不正解」と出力されるということしかわからないと思います。

こういったプログラムを「バイナリ解析」することで『「CTF」という文字列を入力すれば「正解」と出力される』という動作まで特定することが可能になります。

この「正解」を CTF では『 Flag 』と呼びます。

解析の具体的な内容について

ここまででバイナリ解析の概要が掴めたかと思います。
それでは具体的にどういうことを行って解析するのかを説明していきます。

結論から言うと、バイナリを逆アセンブルしてアセンブリ言語を生成することで解析を行います。

アセンブリ言語は昔使われていたプログラミング言語の一種で、以下のようなコードです。

mov eax, 0xb
mul c
mov c, eax

アセンブリ言語については CTF で実際に問題を解きながら覚えていくことにして、アセンブリ言語を生成する理由は『バイナリから読み取るのは不可能に近いので、せめて人間が理解できるアセンブリ言語に変換してからプログラムの動きを見ていこう』ということです。

アセンブリ言語については以下のサイトが参考になります。

アセンブリ言語入門

ここで疑問が浮かぶのは、それならわかりづらいアセンブリ言語じゃなくPython のようなプログラミング言語に変換すればいいじゃん!ということです。
この行為を逆コンパイルと言います。

しかし、逆コンパイルは逆アセンブルと比べて精度が低いです。

この理由は、Python や C言語のようなプログラミング言語は人間寄りに作られており各命令に対して数十の機械語に翻訳されるため、機械語からプログラミング言語に直すのが苦手だからです。

対してアセンブリ言語はハードウェア寄りの言語であり、機械語と1対1の関係です。そのため、機械語からもアセンブリ言語は戻しやすく、精度の高いコードが手に入ります。

このことから、解析はアセンブリ言語で行われることが多いようです。

Forensics

フォレンジック解析のことです。

フォレンジック解析とは、HDD や USB メモリといったコンピュータの記憶媒体に保存されているファイルログなどから犯罪捜査の法的証拠を探し出すことを指します。

解析することで、プロセス実行時刻を割り出したり削除されたファイルを復元し、犯罪の証拠となるデータを見つけることが可能になります。

CTF では、ディスクイメージやメモリダンプ(ある時点でのメモリ内容)、更には画像ファイルやzipファイルなども扱われるようです。
これらのデータを与えられて、その中から Flag を見つけよ!というのが CTF の問題です。

どうやって解析する?

データの種類によってアプローチは異なるようですが、どの場合も基本はツールを使用するようです。

ディスクイメージからファイルを復元するツール(TestDisk)や、メモリダンプを解析するツール(Volatility) があるようです。

使い方は実際の問題を解く際に紹介できればと思います。

参考にさせていただいたサイトは以下です。

Forensics入門(CTF) - Qiita
社会人になってからCTFにちょくちょく出るようになったのですが、先日出たCSAW CTF 2016であまりにもForensicsが解けなかったので、どんなテクニックがあるか自分のためにまとめておこうと思います。 最早実務のフォレンジ...

Pwnable (Pwn)

脆弱性を突いてサーバの権限を奪う手順を踏む問題が Pwnable に分類されます。

問題としては、以下の2種に大別されます。
・リモートエクスプロイト
・ローカルエクスプロイト

リモートエクスプロイトでは、問題文にホスト名とポート番号が記載されており、そこに接続することで問題となるアプリケーションが実行されます。
併せて問題として与えられるバイナリ等と組み合わせてこのアプリケーションの脆弱性を見つけ、その脆弱性を攻撃することで権限を奪い Flag を見つけ出すまでが基本的な流れになります。

ローカルエクスプロイトでは、サーバに SSH 接続して問題を解きます。
SSH 接続したユーザでは Flag が書かれたファイルを開けないので、サーバ内の実行ファイルを攻撃して権限を奪い、Flag を読み取ります。

どうやって脆弱性を見つける?

脆弱性を見つけるアプローチとしては、まずプログラムが正常に終了しない(落ちる)入力を見つけます。
そのような状態となった場合は、意図しないアドレスに入力値が書き込まれている可能性が疑われます。

例えば、バッファオーバーフローの脆弱性がある場合には意図しない大きさの入力値を与えることでバッファ溢れを起こしてプログラムが落ちます。

プログラムが落ちる入力値を見つけることができれば、次はその動作がプログラムのどのコードで発生しているかを特定します。

ソースコードが与えられている場合はそのコードを読み解き、ソースコードがわからない場合には先述したバイナリ解析によって脆弱性があるコードを見つけます。

どうやって攻撃する?

攻撃するために、エクスプロイトコード(攻撃プログラム)を作成する必要があります。
例えば、バッファオーバーフローの脆弱性がある場合には以下記事に書いたような流れになります。

この記事では、エクスプロイトコードの作成についての細かい流れまでは書いていません。詳細については実際に CTF を解く際に解説したいと思います。

Web

Web アプリケーションの脆弱性を突いて(XSS・SQLインジェクション・OSコマンドインジェクションなど)Flag を取得する分野です。

普段 WEB ページを閲覧する際には意識しませんが、WEB ページに表示されている情報以外にも多くの情報をクライアントサーバ間でやり取りしています。
WEB ページに表示されている情報以外も活用することが、Flag を取得する上で必要な考え方になります。

WEBアプリケーションに攻撃を仕掛けるアプローチとしては、典型的なパターンとして以下が挙げられます。
・WEBページ上にある入力フォームから攻撃を行う
・プロキシツールで通信の内容を書換えることで攻撃を行う
・ファイルアップローダがある場合は、悪意あるファイルをアップロードする
・既知の脆弱性情報を片っ端から活用する(最後の手段)

WEB ページ上から攻撃を行うには?

入力用のテキストボックスが用意されている場合は、そこから攻撃を行える場合があります。
例えば、本ブログで紹介した SQL インジェクションや PHPコードインジェクションはこの方法で攻撃を行っているので、以下記事を参照いただければと思います。

プロキシツールで通信の内容を書換えるには?

まず、プロキシとはWEBサイトへの通信を仲介してくれる存在です。
このプロキシで一旦通信を受けて、任意の内容に書き換えてからWEBサイトに通信を送ることができます。
そのため、WEBページで用意されているフォームに入れることができない情報についても書き換えることができます。

本ブログでは以下の記事でプロキシツールを使用した攻撃を紹介しています。

ファイルアップローダの制限を回避するには?

CTF でファイルアップローダが用意されている場合は、十中八九問題に関連しているそうです。
悪意あるファイルをアップロードしてそれを実行できればそれ自体が脆弱性なのですが、制限がかかっていて特定の拡張子のファイルがアップロードできなかったり、アップロードしたファイルにアクセスできないようになっています。

アップロードできない場合には、ファイルを偽装することでアップロードできるようにするといったアプローチが考えられます。拡張子の判断をファイルのヘッダで行っている場合には、そのヘッダを画像ファイル用のものに書き換えるといったことでアップロードできるようになる可能性があります。

また、アップロードしたファイルにアクセスできない場合には、ディレクトリトラバーサル攻撃といった別の脆弱性を利用したアプローチが考えられます。

ディレクトリトラバーサル攻撃については本ブログの以下記事で紹介しているのでご参照いただければと思います。

上記のようなアプローチで脆弱性を攻撃し、シェルを奪うことで Flag をサーバ内から見つけます。
/var/www/ 配下の公開ディレクトリや、ルートディレクトリ直下にあることが多いようです。

Network

pcap などのパケットキャプチャファイルが問題として与えられます。
このパケットキャプチャファイルを Wireshark 等で解析し、Flag を見つけることになります。

Wireshark でパケットキャプチャを開くと、以下のように中身を見ることができます。

Network の問題は、以下2つの形式に大別されます。
・パケットキャプチャファイル内から Flag を見つけ出す
・パケットキャプチャファイルの情報をもってサーバにアクセスして Flag を見つ出す

パケットキャプチャファイル内から Flag を見つけるには?

パケット数が少なければ上から1つずつ見ていけばいいのですが、膨大な量の場合は非効率であり、見落とす可能性もあります。

そのため、Wireshark のフィルタリング機能を使用することは必須になります。
その上で、他の通信と内容が異なるパケットを見つけます。例えばレスポンスコードが異なるなど。
そういった通信を特定し、詳細な中身を見ていくことで Flag を見つけていきます。

パケットキャプチャファイルの情報からサーバにアクセスするとは?

この出題形式の場合は、以下のような情報が与えられることが多いようです。
・IPアドレスやFQDNなどの接続先情報
・パケットキャプチャファイル

IPアドレスやFQDNなどの接続先情報が与えられた場合には、ポートスキャンで接続可能なポートを特定し、そのポートに接続した際の通信を解析していきます。

パケットキャプチャファイルが与えられたがその中に Flag がない場合には、そのファイルにある通信と同じ通信を実際に発生させてヒントを得ます。
例えばサーバにログインする際の通信内容が含まれている場合には、そのパケットに書かれているアカウント情報でログインし、Flag を取得するといった流れになります。

Cryptography( Crypto )

暗号技術に関する問題が該当します。

基本的には、暗号文と鍵となる情報が与えられて、暗号文の元の文字列が Flag となる問題形式のようです。

Crypt の解説でよく使われる、最もシンプルな暗号方式である「シーザー暗号」で説明します。

問題として以下が与えられたとします。

【問題】
暗号文:ngu
暗号方式:シーザー暗号
鍵:3

この暗号文の元の文章が Flag になります。

まず、シーザー暗号とは n文字後ろにずらすというアルゴリズム(暗号方式)です。この n文字というのが鍵情報になります。

つまり以下のような法則で暗号文を生成したということになります。

ngu の元の文字列は「kdr」ということがわかります。この文字列が Flag になります。

なお、このようなシンプルな文字列、暗号方式なら良いのですが、複雑になれば人間が計算するのは不可能になってくるので、必要に応じてプログラムを作成する必要も出てきます。

また、複雑な暗号になればなるほど数学の知識も必要になり、かなり難度は高いようです。

いざ CTF にチャレンジ

上記でなんとなくですが、イメージはできたと思います。細かいツールの使い方や前提知識は問題解きながら覚えていきましょうということで、実際に問題を解いていきたいと思います。

インターネット上には、さまざまな CTF 問題が「常設 CTF」という形で公開されています。
国内から海外のサイトまでたくさんあり、入門者はどれにチャレンジしたらいいかわからないと思います。

入門者向けなのはどれだろうと思い調べてみましたが、どうやら CpawCTF というサイトが入門者に良いみたいです。

CpawCTF - Main page

まずはこちらの問題を解き、解き方とそれに関する知識をセットで記事にしていきたいと思います。

参考

本記事は、セキュリティコンテストチャレンジブック(通称:ハリネズミ本)を参考にさせていただきました。
技術的な内容が詳細に書かれており、まだまだ読み切れていません。常設 CTF にチャレンジしながら読み進めていきたいと思います。
みなさんもぜひご購入いただき一緒に CTF にチャレンジできればと思います。

※Amazonアフィリエイトを使用しています。

以上です。

コメント

タイトルとURLをコピーしました