2017年8月19日土曜日

セキュリティキャンプ全国大会2017に参加しました

2017年08月14日から08月18日まで、東京都府中市で開かれたセキュリティキャンプ全国大会に参加してきました。ここでは私の参加した集中Xコースのx86OS自作ゼミでの活動について書こうと思います。
今回作ったOSは
https://github.com/ptr-yudai/osdev
にあります。(キャンプ終了時点ではバグだらけです。) もしかしたらOSに名前を付けて別リポジトリでまた0から作り始めるかもしれません。

事前学習

まずは作りたいOSについて目標設定します。これは途中で変えてもいいのですが、最初は「ディスクから削除されたファイルを救出できる」という目標を建てました。(応募時は「ディスクを読み書きできるOS」を目標にしてました。)OSは0から作るのですが、私の場合6月くらいから作り始めています。目標はともかく、32ビットOSを作るために最初にやることは大きく分けて保護モードへの移行と割り込みの有効化なのですが、これらを7月始めくらいに完成させました。(サイボウズで07/03にIDEの話をしているのでこのくらい?)そこからIDEでハードディスクを読み込むのを実装するのですが、結構難しかったのを覚えています。ですが、この辺りまでは正直osdevのwikiやforumを参考にしてサクサク作っていた感じです。(1日平均1時間くらいしか時間を取れなかった。)ここからが地獄の始まりです。ディスクを直接読むのでファイルシステムを扱う必要があるのですが、最初にFAT, NTFS, EXTのどれにするか迷いました。世界的にシェアが高いのはFATかNTFSなのですが、FATは簡単すぎると思ってNTFSを目標にしてしまいます。MBRやブートセクタは簡単でしたし、MFTと呼ばれる各ファイル(ディレクトリやその他システム設定も)のレコードの構造も仕様通りに解析していました。ディレクト以下のファイル一覧は$INDEX_ROOT($INDEX_ALLOCATION)を見れば分かるので、これでルートディレクトリのlsもできました。しかし、ここで躓きます。$INDEX_ROOT($INDEX_ALLOCATION)にはINDEX_RECORDというのが並んでいて、それぞれがディレクトリ下のファイルの情報を持っているのですが、FILENAMEという属性しか持っていないのです。てっきり「ファイル情報」+「そのファイルのレコード本体へのポインタ(クラスタ番号)」みたいなのを持っていると思ったのですが、本体の場所が分からないのでFILENAME以外の情報は分かりません。ここで1週間以上悩んで、$MFTという「全てのファイルへ参照できるファイル」というものを使えばいいんじゃないかと思い、$MFTのDATA属性を辿ると目的のファイルが見つかりました。これで一件落着したと思ったのですが、$MFTのDATA属性をどこまで辿ればいいのか分からず、またファイル数が多いときは時間かかるんじゃないか、と思っています。これは未だに線形探索の実装しているので、誰か正しい方法知っていたらここかtwitterで教えてくださいm(_ _)m
 

キャンプ一日目

基調講演でサイバーディフェンス研究所の方がフォレンジックについてお話されたので聞いていて、ファイルを削除してもデータは残るよ、と言っていたのですが残念ながらその詳しい参照方法は説明されませんでした。キャンプ終了後に聞こうと思ったのですが、すぐに帰ってしまったらしく、分からずじまいになりました。
 

キャンプ二日目

なんだかんだでとりあえずディレクトリ一覧(fls)までは作ってきたので、icatとかistatとかを初日に実装します。他には細かいバグ潰しやコマンド入力画面を少しきれにしたりしていました。また、チューターの方が"File System Forensics Analysis"という本を貸してくださり、これが結構いろんな情報が書いてあり役に立ちました。そんなこともあって当初の目的であった削除済みファイルの復元には成功しました。このころ他の参加者はみんなページングとかタスク切り替えとかOSらしいことをしていたので、一人だけこんなOS作ってていいのかと思いながら二日目終了。
 

キャンプ三日目

 このころ、自作OSにLinuxにもWindowsにも無いオリジナリティを組込むという課題(?)を与えられます。ファイル復元なんて復元ソフトでもできますし、SystemRescueCdというもっと高機能なOSもあったので、この辺からフォレンジックに特化したOSを目ざし始めます。具体的にはTSKやAutopsyなどに付いているタイムライン機能やファイルカービングを付けようと思います。この日は画面をスクロールさせる機能を付けました。それから、"File System Forensics Analysis"に$LogFileというフォレンジックっぽいファイルがあったので、それを解析する機能を付けることにしました。しかし、このファイルはまだ仕様が解明されていないようで、結局$LogFile内の特定のファイル名を探索する機能だけを付けて終わりました。Microsoftは早くNTFSの仕様公開してください。また、タイムライン機能のために時間でソートする必要があるのですが、講師の方に赤黒木を使えば速いという話を聞きます。夜にプロに赤黒木について聞いたのですが、あと1日で作るには実装コストが高かったので線形リストを使ってO(n)O(n^2)で妥協することにしました。

キャンプ四日目

 最終日はタイムラインを実装しました。そこでまたオリジナリティについて問われるのですが、「OSにすることでディスクダンプの手間が省ける!」と言うと「LinuxのLive Bootでツール動かしちゃダメなの?」という正論をいただきます。そこで、それに加えて省メモリを売りにすることにしました。具体的に省メモリとは何かを定義するため、x86でファイルシステムを扱うOSについて調べると、Win 95の8MBでの動作が調べた限り最小でした。私のOSは2MBでも一応動くので、これなら省メモリと言えるだろうということにしました。(実は2MBだとタイムラインでファイルパスが取得できないので、タイムラインにはファイルパスを調査しないオプションを付けてごまかしました。)四日目の後半でコマンドを使うにつれてメモリ使用量が増えていることに気付いたのですが、何をfreeし忘れているのか分からず終了。今迄もfree忘れに気づくためにfreeチェッカーみたいな機能を付けていたのですが、そもそもその機構に問題があったらしく、全然freeできていませんでした。これは修正ポイントです。ですが、削除されたファイルが復旧できるというインパクトが強いので講師の方に成果報告の発表者として選んでいただきました。
 

その他

 キャンプでは専門講義以外にもグループワークや企業プレゼンなどがあったのですが、それについては他の参加者がたくさん書いてくれているので私からは書きません。ただ、BoFで海外のセキュリティ関連イベントについて聞いて、めちゃくちゃ海外イベントに参加したくなりました。何とかお金を使わず海外イベントに参加できる方法を模索しています。誰か連れてって〜。

まとめ

 「ファイルの読み書きができるOS」という最初の目標から「フォレンジックが得意なOS」に変貌しましたが、結果良かったと思います。OSの機構についても少し学べましたし、講師の方にOS開発で便利なライブラリをいくつか教えてもらえたので今後使ってみようと思います。私はずっとNTFSでしたが、周りの人との交流もあったのでマルチタスクがどんなものか、ページングをどう設定するか、64bit難しい、などなど自分が触れていない部分も知ることができました。参加前は「選択でも良かったかな〜」とか思っていましたが、今はX-Xを選んでおいて本当に良かったと思っています。
あと、ずっとNTFSに漬かっていたので特定のファイルを見つけるくらいならバイナリエディタで読める体質になってしまいました。

期待をはるかに上回った内容のセキュリティキャンプでした。運営、協賛企業等、講師、チュータの方々は本当にありがとうございました。参加者の方々はお疲れさまでした。これからもお世話になると思うのでよろしくお願いします!