Capture the flagのススメ　-超初心者向けバイナリ解析-　その1


先日東京で行われたCapture the flag for beginners(ctf4b)に行ってきましたので備忘ついでに記事にします。

#注意事項
この記事はCTF超初心者の備忘録であるとともに、少しでもCTFに興味を持ってくれたら嬉しいな♡程度の記事なので細かいところは説明しませんしできませんので予めご了承ください。
ですが、何か理解が間違っている等あればコメントなどで指摘してくれたら幸甚です。

# CTF(Capture the flag)とはなんぞ？
ctf4bで初めてCTFという競技を理解しました。
普通は、CTFというと陣取りゲームのことを指すようですが、
コンピュータセキュリティでは少し意味が違い、パケット分析、プロトコル解析、システム管理、プログラミング、暗号解読などの技術を利用してFlag(脆弱性)を見つけ出す競技のことを指します。

かなり上級者向けに聞こえますが、むしろセキュリティ初心者こそやるべきだと思います。
楽しいし勉強にもなる・・・最高じゃないっすか。
それにバイナリ読めるようになりたいじゃないっすか。
ロマンじゃないっすか。

# 問題の分野について
※今回はリバースエンジニアリングの途中までしか説明しませんので、それ以外は読み飛ばしてもいいっす。

>**リバースエンジニアリング**
Binaryとも呼ばれる。基本的にはシリアルキーのクラッキングなどと同じ技術を用いてフラッグ（旗に相当するファイルの内容）を奪取することで得点となる。

>**Forensics**
HDDやUSBメモリや物理メモリのイメージファイルを解析し、その中からフラッグを奪取することで得点となる。

>**Pwnable**
プログラムの脆弱性を突き、不正侵入・不正昇格をすることで得点となる。
基本的な部分はBinaryと同じ（攻撃対象の解析）だが、脆弱性の発見及び脆弱性を攻略するExploitコードを記述する技術が必要である。
サーバ内のフラッグを奪取することで得点となる。

>**Web**
ウェブアプリケーションの脆弱性を突いて（XSS・SQLインジェクション・OSコマンドインジェクションなど）サーバ内に侵入し、フラッグを奪取することで得点となる。

>**Network**
ネットワークのパケットを解析し、その中からフラッグを奪取することで得点となる。
ネットワークの基礎的な知識と、それぞれのプロトコルに関する深い知識が要求される。

>**Miscellaneous**
上記ジャンルに分類できない、またはセキュリティ関係の雑学やパズルなどの問題が出題される。

[Wikipediaより](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E3%83%BC%E3%83%BB%E3%82%B6%E3%83%BB%E3%83%95%E3%83%A9%E3%83%83%E3%82%B0)

今回はリバースエンジニアリングを説明します。
バイナリ解析は楽しいぞぉ！！

##バイナリ解析とは
バイナリ自体はコンピュータが理解できるように「０」と「１」のみで表記されたデータ形式のことです。こんなの読めない。(頭があれな人は読める)
機械語やデータなどはすべてメモリに配置されます。
メモリは下の図のようなアドレスとその内容が入る場所の2組の配列が並んでいるイメージになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146681/d163c4b9-a5bc-0c57-cb33-a441b83793fb.png)
んで、そのような実行ファイルなどを解析するのがバイナリ解析(のはず)です。
CTFでは「Rev」とか「Reversing」と言われるようですね。

##どういう問題形式なのか
例えば・・・
-Linuxの実行ファイルの解析
-Windowsの実行ファイルの解析
-Androidアプリの解析
-その他様々なバイトコードの解析

基本的に各OSで広く採用されているELFバイナリ(ELF: Executable Linkable Format)の解析を今回は説明しようかと思います。
むしろその他は知りません。

##機械語の翻訳
先程も書きましたが、機械語なんて読めないです。

*b8 0a 00 00 00*

これ読めないでしょ？
つまりそういうことです。

そこで必要になってくるのが機械語の翻訳です。
日本語に翻訳できたら最高なのですが、そうは問屋が卸さないわけでして・・・
妥協案として、**機械語と1対1で対応した言語**に翻訳してやります。
機械語と1対1で対応して、かつ人間にも辛うじて読める言語。。。
そう、アセンブリ言語ですね。

##アセンブリ言語
アセンブリ言語には構文が2つ(以上？)あるようで、Intel記法とAT&Tがあります。
これはCPUが理解できる言語なのでCPU毎に異なるのですが、1つ覚えれば大抵は類似しているので解析は容易です。
今回は一般的なIntel記法について説明をします。
因みに先程の機械語をアセンブリ言語に直すと、

*b8 0a 00 00 00*
↓
*mov eax, 0xa*

になります。
結局読めねぇって？
機械語が人間に歩み寄ってくれたのでこちらも機械語に歩み寄ってあげる努力をしましょう。
恋愛と一緒ですよ。

上記のように機械語からアセンブリ言語に変換することを、「**逆アセンブル**」と言います。
それでは上記のアセンブリを参考に読み方を説明します。

**Intel記法**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146681/88ce580c-3409-a8ed-754a-ff2db7795284.png)

①転送先：ディスティネーションオペランド
②転送元：ソースオペランド

オペコードをもとにオペランドの操作を行うのが基本的なアセンブリの読み方になるっす。
今回のオペコードは[mov]で、これは[move]の略です。
Intel記法では右から左へが基本ですので、この場合、eaxに0xaを代入するという命令になります。
Python言語で言うところの、
**eax = 0xa**
ですね。
あとオペコードは複数あるのでそれを覚えましょう。

[0から作るソフトウェア開発](http://softwaretechnique.jp/OS_Development/Tips/IA32_instructions.html)サイト様がまとめてくれていますのでそちらを参考にしてください。
基本的には「mov」以外に、以下の命令を覚えれば良いと思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146681/07e4d3c2-7bd1-b007-caa1-a9f507a173ba.png)


##レジスタ##
CPUにはデータを操作するための変数のようなレジスタと呼ばれるデータを格納する場所がいくつか用意されています。
一般的なプログラム言語の変数は自由に名前や用途を決めることができ、数にも制限はありませんが、レジスタはCPUの中にあらかじめ決められた個数だけ用意されていて名前とその用途も決まっています。
実は先程利用した**eax**もレジスタの1つです。
レジスタには以下のようなものがあります。
今ではほとんどが32ビットですので、その他は覚える必要はまぁない気がします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146681/4b4286bf-e439-36fe-602c-f5a52448273a.png)



#終わりに
ここまででとりあえず第1回は終わりにしようかと思います。
Reversingの魅力は今のところ全く説明できていないわけですが、ここからが面白いところだから！まだ先っちょだけだから！次回も見てくれたら分かるから！

次回はReversingの解法手順について説明します。
実行ファイルを実際に解法する方法や、Flagの見つけ方について記事にしてみたいと思います。
思ってるだけですけどね。

##参考サイト様
[0から作るソフトウェア開発](http://softwaretechnique.jp/OS_Development/Tips/IA32_instructions.html)サイト様
→命令一覧　大変助かりました。

[アセンブリ言語入門](http://ext-web.edu.sgu.ac.jp/koike/CA14/assembler_content.html)サイト様
→画像等引用させていただきました。
 こっちを見たほうがアセンブリ言語について非常によくわかります。

[SCCON for Beginners](https://2017.seccon.jp/news/seccon-beginners-5.html)
→この無料セミナーは大変興味深く、面白かった！この記事を書いたきっかけです。
 ビギナー大会は25/129位でしたけどまぁ初めてにしてはね？それなりにね？

それでは次回の記事にてお会いしましょう。

[Capture the flagのススメ　-超初心者向けバイナリ解析-　その2](https://qiita.com/ebonight/items/f384ac42f9ab2ddb76b8)

###自分のサイト建てたので宣伝させてくれ。
よろぴく☆
[ほげふがな日常](http://www.hogehoge-note.com/)