セキュリティ・キャンプ全国大会2018~応募編~
※他の方の応募用紙もまとめたサイトを@hikalium氏が作成してくださっています。
そちらもご参照ください。
seccamp.jp
はじめに
セキュリティ・キャンプ全国大会2018のアンチウィルス実装🚚の選考を通過したので応募用紙で何を書いたかを書いておきます。
現状として自分がなぜ通ったのか全くわかりません。
これまでの私の他イベントへの参加状況を一応書いておきますと、ミニキャンプ山梨に参加し去年応募した全国大会に落ちた。というような感じになってます。
応募期間中は基本的に暇だったので、ずっと応募用紙に張り付いてました。
他の応募用紙晒しとかだと、「〇〇さんや△△さんありがとう!」みたいなのがあって僕もそういうのをやりたかったのですが、残念ながら入学したてでそこまで世話を焼いてくれる人物がいませんでした…残念…
また、文章の中でおかしい点などがあると思いますが、それは僕の技術力や知識の不足によるものです。
あと、僕はキレイな文章を書くのが苦手というのがあり、応募用紙内の文章についてはかなり難読化されてると思います。
改めて選考をして頂いた講師の方々には、選考用の書類が多い中僕の文章のような駄文でも読んで選んで下さりありがとうございます。
頑張ってやっていきたいと思います。
セキュキャン受かってました
— site (@site0801) June 14, 2018
ゼミはアンチウィルス実装ゼミです
よろしくお願いします pic.twitter.com/JSidkbIYt7
本題
共通問題
共通問題については、恥ずかしいしアレなので要約して書いていきたいと思います。
共通問題1 マルウェア(コンピュータウィルスの総称です、以下マルウェアと統一します)とは何か/どういうことをするものか、自分の考えを書いてください。
- IPAが公開している「コンピュータウィルス対策基準」について書いていました。
- また、(巷で話題の)c01nh1veなどをウィルスとみなすかどうか
- 実際に最新の大きな脆弱性等を例に挙げてウィルスの定義についての話
- マルウェアの開発者や配布者の損得などを考えて最終的にウィルスは何を目的とするのか
共通問題2 マルウェアを検知するアイデアを書いてください。どこで、どのようなロジックで、何を検知するのかを意識して書いてください。また機械学習や深層学習のネタを書く時は、実験データや特徴量、アルゴリズムなどをちゃんと書いてください。
共通問題3 アンチウィルスソフトウェアでは、しばしば誤検知(過検知)の問題が起こります。誤検知とは、本来マルウェアではないプログラムを、動作や特徴がマルウェアに似ているため、マルウェアと判断してしまうことです。例えば、オンラインゲームのチート防止プログラム、オープンソースな署名がないビデオ再生ソフトなどです。あなたが作るアンチウィルスでは、このマルウェアに似た動作や特徴を持つプログラムに対して、どのような判断をしていきたいと考えていますか?
- トレ〇ドマイ〇ロ社ウィル〇バス〇ーとINA〇OFT製ソフトウェアの誤検知問題について
- そこから自分のアイデアを書いていった。
共通問題4 Linuxプログラミングについて、経験がある項目を複数選択してください。
1. Python, Ruby, Perlなどを用いてコマンドラインアプリケーションを作成したことがある
2. C/C++などを用いてメモリを自身で管理しながら処理をおこなうデーモンを作成したことがある
3. Procfsやシステムコール(libcシステムコールラッパー)を用いてカーネル内の情報を取得、設定するアプリケーション/デーモンを作成したことがある
4. Linux Kernel Module/Linux Security Moduleを作成したことがある
5. Linuxカーネルに機能を追加もしくは修正したことがある
6. Linuxカーネルにパッチを投稿したことがある
1
共通問題5 ELFフォーマットのバイナリに関して、知識・経験がある項目を複数選択してください。
1. コンパイルして実行したことがある
2. gdbなどデバッガを用いてデバッグしたことがある
3. readelf, objdumpを用いてELFフォーマットの情報を見て理解できる
4. LD_PRELOADを用いた関数フックを行った場合の動作を説明できる
5. ELFローダを自作できる
1,2
共通問題6 PE、ELF問わず実行形式のバイナリのマルウェア解析について、経験がある項目を複数選択してください。
1. VirusTotalの情報を見て、マルウェアかどうかをある程度確信を持って判定できる
2. 動的解析によって、アーティファクト(マルウェアによるファイル、レジストリの新規作成及び変更、削除、通信先、通信ペイロード)を抽出できる
3. サンドボックス(Cuckooなど)の実行結果を用いて、マルウェアかどうかをある程度確信を持って判定できる
4. デバッガを用いてパックされたマルウェアをマニュアルアンパッキングできる
5. ディスアセンブラを用いて静的解析を行い、特定動作のコード部分(例えばアンチデバッグ)を特定できる
6. プロセスのメモリダンプから悪意のあるコードのインジェクション部分を特定し、その挙動を解説できる
1
選択問題
※ここは私は「Z4)DPDKを用いた圧倒的に高速なNetwork-based IDS/IPS」しか選択しませんでした(というよりもそれ以外は分からない or 難しい分野ばかりだった)
選択問題4 以下について今まで手を動かした経験や熱意に基づき答えてください. 全部答えても, いくつかを選択して, 熱心に答えても良いです. 成果は何をやったのか, 何が大変だったか, 何が面白かったか, 等を具体的に示してください.
以下の設問では, あなたがこれまでどれだけ「手を動かしてきたか」を評価します. 手を動かすことが必須項目ではありませんが, 技術力の高い方は皆たくさん考えてたくさん手を動かしています. 現状ではそれが世間の役にたつか等をあまり気にせず, 「あなたが技術として面白いとおもうこと, 楽しいこと, 熱中していること, 目標, etc..」を聞かせてください. 応募用紙に入りきらないようなものはURL等を教えてくれればそちらを参照します. 注意ですが, 私の担当範囲では質がPrimaryな評価ポイントです.「応募内容の量が多い == 評価する」という訳では一切ありません.
選択問題A ネットワークや, パケットに関するプログラミングの経験がある場合(入門中も可), どのようなものを作ったのか(作っているか, 作りたいか) 説明してください. また, それらで性能を重視する場合, 高性能通信を実現するにあたり必要なことを説明してください.
まず、これまでに作ったことのあるネットワーク関係のプログラミングについてですが、恥ずかしながら私はこれまでネットワークなどに触れていたにもかかわらず、所謂「socket()などを用いたネットワークプログラミング」というものはほとんどしてきませんでした。(これまではどちらかというと全く別の分野やICTトラブルシューティングコンテストのようなネットワーク構築のようなことをしていました。)
ただし、Pythonのライブラリである"Scapy"を用いてパケットを飛ばす(飛ばした場合にルーターやL2スイッチ、リピーターハブが実際にどのような挙動をするのかというような実験)ということについては行ったことがあります。
また、小俣光之氏の「ルーター自作でわかるパケットの流れ」を高校2~3年生の時に進めていた(C言語のマルチスレッドプログラミングや構造体に慣れていなかったせいもあり、かなり進行は遅く)のですが、資格や校内の試験や授業などで中断されてしまい、最後まで終わらせることはできませんでした。
なので、今回はセキュリティキャンプの応募用紙をきっかけにネットワークプログラミング自体と上記の本について再入門をしました。
ですが、ただ単にプログラムを写経しているだけでは理解が深まらないと考え、C言語の写経の他に別のプログラミング言語でも実装してみようと思い、Pythonで実装してみました。
募集期間中に再入門自体を始めたため、まだまだ途中までしかできていませんがソースコードを送らせていただきます。
GitHub - site0801/hogehogeshark: packet capture
このプログラムについてですが、主な説明についてはリポジトリ内にある"README.md"に書いてあり、プログラムを書くにあたってかなり躓いた(躓いている)点を"memo.md"の方に書きました。(また、開発しているうちに楽しくなってしまったので、今後も開発をしていく所存ですので、評価は提出日時などを比較してみて頂けると助かります)
プログラムの詳しい説明については、ここに書くとかなり長くなってしまう可能性があるので、プログラム中のコメントアウトや"memo.md"に書かせていただきます。(ソースコードを読むにあたって思考する時間を割かせていただくことになり申し訳ございません…)
また、これらのプログラムで構成の通信を実現するにあたり必要なことについてですが、正直まだそこまでイメージが着いていないのですが、今後高速化を図るにつれてPythonという言語では限界を迎えると考えています。
ですので、C言語またはC++言語、最近の流行りとしてRust等が選択肢に数えられるかと思います。
そして、DPDKを用いるに当たって必要となる自作プロトコルスタックですが、これも自分で高速なものを実装していかなければいけないと考えています。
当然高速なプロトコルスタックを実装するには、メモリを自分で管理するようなプログラムを書かなければいけないと考えています。なので、そのようなプログラムの書き方についても身に着けていけないかと思います。
選択問題B 性能を重視する場合, DPDK等の特殊なパケット処理方法を用いることが想定されますが, DPDKはなぜ既存のLinuxのネットワークプログラミングとくらべ, 高性能通信を実現することができるのでしょうか. よく調べて説明してください.
まず、DPDK(Data Plane Development Kit)とはNIC(Network Interface Card)をカーネルを経由してではなく、ユーザーランドから直に触ることができるようになるライブラリです。
また、問題文にも「高性能通信を”””実現”””することができる」と書いてある通り、DPDKは、本来カーネルで行うパケットのヘッダー部分からどのプロトコルかという情報を解析する処理などを、アプリケーションを開発する際に自分で記述することができるというものなので、「DPDKを使えばなんでも早くなる」ということはないということを先に記述しておきます。
そこで、なぜ、NICを触る際にカーネル経由ではなく、ユーザーランドから直に触ることによって高性能通信が実現可能になるのかということですが、従来のカーネル経由では他のアプリケーション等の割り込みを待つことによって、パケット処理の割り込みが増えることによってコンテキストスイッチも増加し、どうしてもオーバーヘッドが増加してしまうという問題があります。
ですが、DPDKでは、PMD(Poll Mode Driver)という特殊なデバイスドライバーが特定のCPUコアを占有し、外部からのパケットを常時監視すること(一般にこれをPolling方式と呼ぶ)によって、割り込みによる処理の中断時間がなくなり、従来のカーネル処理よりも高速にパケットを処理することができます。
以上に記述したことをまとめますと、DPDKではCPUを占有し、ユーザーランドから触れるようにすることによって割り込みなどの無駄な時間を無効化し、高速な通信を実現することができます。
ですが、その際に気を付けなければいけないこととして、「カーネルに処理をさせないことによってパケットがどのプロトコルなのかといったような情報が無いため、自作のプログラムでその処理を書かなければいけない」ということと、「その処理がカーネルでの処理よりも劣っていた場合はその分通信が遅れてしまうという点に注意しなければいけない」というものがあります。
選択問題C 圧倒的に高性能なFirewall等のソフトウェアネットワーク機器について, 作りたいソフトウェアとそれに対するロマンや必要性等を技術的に論してください.
まず、私がDPDKなどを用いて作成したソフトウェアは2つ考えています。
考えている内容は、ファイアウォールの開発とロードバランサの開発の2つです。
まず、FireWallの開発をしたいと思った理由としては、昨今の通信速度の向上とインターネットに接続する機器の増加により、セキュリティ分野においても、より高速な処理が求められています。
FireWallでは、フィルタリングなどの処理部分のほかに膨大な数のパケットの処理を行います。
その部分に、カーネルを通しての処理を行っていると、コンテキストスイッチの回数が増えてしまいます。
なので、それを抑制するためにDPDKを用いたいと思います。それによってCPUコアを占有させてしまうことになりますが、より合計の処理速度の早いFWの開発が実現可能になります。
また、DPDKを用いて通信部分での処理時間を高速化させることによって昨今増えている機械学習などの高負荷の掛かる実装だとしても従来のヘッダー解析などの処理と同じような速度が出せる可能性があります。
これにより、現在も増加し続けている膨大なトラフィックに対して対応することができると考えています。
次にロードバランサです。
ロードバランサでDPDKを用いて開発したい理由としては、大きく分けて3点あります。
まず、DPDKは、所謂プロトコルスタックを必要としない処理で一番力を発揮することができます。
そこで、プロトコルスタックを必要としない(場合によっては必要になる可能性もあります)ロードバランサでこそ、真のDPDKの力を発揮することができるのではないかと考えました。
また、DPDKを用いてロードバランサを開発する必要性としても、昨今のネットワークトラフィックの増加からロードバランサを使用する際に処理するパケットの数も増加していくと思います。
なので、DPDKを用いてロードバランサを開発することは今後必要になってくるだろうと考えます。
選択問題D その他, 私を講師とした場合に「こんな講義を受けたい」や, 「こんなことを知りたい」等あれば記述してください. 選考を通過したあとには, 具体的に何をやっていくかを再度議論するのでその時の材料になります.
ここも恥ずかしいので要約すると
- OSレベルでプログラムを考えた場合にわからないことあるからご教授お願いします
みたいなことを書いていました。