Senchaのブログ

あまり更新しません

セキュリティ・キャンプ全国大会2016 共通問題

 この度、セキュリティ・キャンプ全国大会2016に無事受かることができたので遅ればせながら応募用紙晒したいと思います。そのまま載せるのでお見苦しいところがいくつかあるかもしれません。

共通問題1

(1)あなたが今まで作ってきたものにはどのようなものがありますか? いくつでもいいので、ありったけ自慢してください。

 私が今まで作ったものは自己紹介ページ、Twitterのクライアント、FPGAイーサネットケーブル、ネットワークの構築、があります。情報とはかけ離れてしまいますが金属でコマを作ったこともありちょっとした自慢です。

 私は今まで学校で様々な専門技術を学び知識を蓄えてきましたが、いざ何か作ったかと問われ思い返すとあまり作っていませんでした。ctfのように問題を解く、解析するなどの形式は多くやってきましたが、折角学んだことが半分しか生かせておらず不甲斐ないです。私のクラスでプログラミング研究部の人たちは常に手を動かし何かを作っています。手を動かし常にアウトプットを作ってる人たちは頭が良く様々な技術を持っていて本当に尊敬しています。私は今まで手を動かす、ということはあまりしていませんでした。それは、情報という大雑把なところに面白みを感じれずモチベーションが上がらなかったからです。しかし、セキュリティを学び始めてこの分野にすごく面白みを感じており、モチベーションもかなり高まっています。手を動かし何かを作るというのは今からでも遅くはないと思います。折角セキュリティの勉強をしているので、セキュリティに絡めた物を積極的に手を動かしながら作りたいと思っています。具体的にはセキュアなアプリケーション、セキュアなサーバ、セキュアなネットワークなどを作成・構築したいと思います。

(2)それをどのように作りましたか?ソフトウェアの場合にはどんな言語で作ったのか、どんなライブラリを使ったのかなども教えてください。

 共通問題1-(1)で挙げた私が今まで作ってきたものは以下のようにして作成しました。

 自己紹介ページを作成したときにはhtmlとPHPを使用し作成しました。どのようなホームページかというと自分の名前、生年月日、学校名などが記述してあります。そしてアカウントでログインでき、ログインユーザーページでは自分の自己紹介文が設定できるようになっています。ログインしたときCookieを使用しセッション管理ができるようにしました。

 TwitterクライアントはJavaを使用して作成しました。Twitter4Jライブラリを使用しPCからTwitterを見られるようにしました。外観などはSwingを使用しツイート用のテキストフィールドとツイートボタンの作成、フォロワーのツイートを見るタイムラインを作成しました。元々、Twitterのクライアントを作ろうと思ったのはJavaを勉強してみたいと思ったからです。そこからGUIでのアプリケーション作成に興味が出て普段よく使うTwitterを作ろうと思いました。Javaの参考書を買い、Javaの基礎から勉強し始めたのですがこのとき初めてオブジェクト思考というものを知りました。今までC言語しか詳しく勉強してこなかったので、Javaで初めて触れたオブジェクト指向プログラミングが難しくとても苦労しました。しかし、勉強していくうちにオブジェクト指向の大切さを実感しました。進みが悪くなった時には友人にどのようにクラスを継承したら上手くいくのかなどを聞き、試行錯誤しながら作りました。良い出来とは言えないですがJavaGUIアプリケーションの作り方を学べて良かったと思います。このTwitterクライアントを作ったときはセキュリティについて意識していませんでしたが、今後アプリケーションを作成することがあったらセキュリティに気を配って作ろうと思います。

 学校で実験実習の時間にFPGAを作成したときはFPGA作成キッドを用いて抵抗、ダイオード、スイッチ、画面、ROM、マイコンをはんだで取り付けました。各部品がとても小さく取り付けるのに大変苦労をしました。1回間違えてマイコンを取り付けてしまったときは取り外すのに自分だけではできずクラスメイト、先生方の力を借りて取り外すことに成功しました。普通はマイコンの取り付けを間違える人はあまりいないそうなのですが自分はその数少ない1人に入ってしまいました。ですが取り付けたマイコンをもう一回外すという貴重な体験ができ、なおかつはんだを用いて外す技術を身につけられたことは良かったと思っています。そのFPGAは今授業で使用しています。Verilogを使いスイッチで発光ダイオードの制御や簡単なグラフィック制御などができるようになりました。

 イーサネットケーブルはcat5とcat6のケーブルを作りました。cat5はネットワークの授業で作成し、cat6はRasberry Pi2とスイッチを接続する丁度いい長さのものがなかったので作成しました。そのとき、ゼミや後輩が使うかもしれないからということでいくつも作りました。おかげでcat6のイーサネットケーブルを作る速度には少し自信があります。またイーサネットケーブルを大量に作ったことで色の配置も覚えられました。

 ネットワーク構築ではCiscoのルータを用いてサブネット化をしました。ハイパーターミナルからコマンドでIPアドレスプロトコルを設定しました。設定が終わった後は実際にpingを飛ばしきちんと通信が行われているかも確かめました。またルーティングテーブルを確認しどのように作成されているか、どういったネートワーク構成になっているかについて確かめました。

 金属のコマを作成したのは高専1年生のときです。私の高専では1年生は専門で別れておらず機械系、電気系、情報系の基礎を全て学びます。そのときに機械系の実験で半期をかけて金属のコマを作成しました。最初に菱形、太い円柱、細い円柱の3つの金属が与えられ、それぞれの部品を旋盤、フライス盤を用いて削り、ボール盤で穴を開けました。最後にはそれらの部品を組み合わせてコマを作り、誰が一番長くコマを回せるかで勝負しました。自分は早々に負けてしまいましたが・・・。コマを作る実験の途中には箸休めとして鋳造も行いました。

 今まで作ってきたものは以上のようにして作成しました。最後の製作物は情報の分野とは少々異なりますが現状に満足せずこれから様々な自慢できるものを作りたいです。

(3)開発記のブログなどあれば、それも教えてください。コンテストなどに出品したことがあれば、それも教えてください。

 私はブログを書いたことや、コンテストに出典したことがありません。ですが、Twitterのクライアントを作ったときはインターネット上のブログに大変助けられました。他にもRasberry Pi2にCentos7をインストールしサーバーを立てるのにも、ブログからやり方などを学び大変助かったことをよく覚えています。

 私はブログをやっていませんが、そういった先人の知恵は大変ありがたいものです。ですので、私も十分な知識を身につけ、アプリケーションの開発をしたときのやり方、サーバーの立て方、ctfの問題の解き方などをブログに載せこれから学ぶであろう初心者にとって良い知識を提供できるようにしたいと思います。

 また、私がセキュリティの勉強をし始めようと思ったとき、何から始めて良いか分からずこの分野に関して入り口がとても狭いように感じました。実際セキュリティは様々なところで必要になっているものです。ですのでこれからセキュリティを学び始めたいという人の為にも、ブログなどで興味を持ってもらえるような学習用の教材としてセキュリティに関しての情報発信をしていきたいと考えています。

共通問題2

(1)あなたが経験した中で印象に残っている技術的な壁はなんでしょうか?(例えば、C言語プログラムを複数ファイルに分割する方法)

 新しい分野の勉強や新しい技術の勉強を始めると私は必ず技術的な壁にぶつかります。私は今までJavaでアプリケーションを開発するときや、PHP、htmlなどを使いWebサイトを開発するとき、python正規表現の勉強をしたときなど様々なところで技術的な壁にぶつかりました。このセキュリティキャンプの応募課題である選択問題8を解いたときもアセンブリ言語には初めて触れたので技術的な壁を感じました。

 様々な技術的な壁を感じた中で私が経験している中で特に印象に残っているのはC言語の動的配列、arraylistの使い方です。学校の課題で「入力された数字をarraylistを用いて常にソートとした形で表せ」(arraylistを用いて入力された数字を常にソートした形で表せ)というものが与えられました。当時C言語に対して苦手意識が高く、この課題を解くのに時間がかかりました。

 arraylistmalloc関数を使いメモリを割り当て、ポインタによって次のデータを参照して連続した配列を表現しています。また削除するときや動的配列の途中にデータを追加する場合はポインタを繋ぎかえ(繋ぎ直し)、参照するところ(先)を変えて(更新して)表現します。

 初めに教科書に書いてあるarraylistの説明を読んだときに全く理解ができなかったのは自己参照型構造体であるといった点でした。

struct list {
    struct list *next;
    int data;
}

上記のように宣言した時の「struct list next」とはどういうものなのか、どういった働きをするものなのか、想像がつきませんでした。教科書で「struct list next」は自分自身を参照しているポインタ変数でありnextは次のノードを指しています、と説明されていました。私はこの説明では全く理解ができずコードが書けずにいました。そこで、教科書に載っていたサンプルコードをとりあえず読んでみました。しかしポインタについて勉強不足でした。(←勉強不足でどうなったかある程度書いた方がいいかも「勉強不足だったため、動作内容が全く分からなかった。」など)

struct list *head = NULL;
struct list *one, *two;
int key;

one = (struct list *)malloc(sizeof(struct list));
two = (struct list *)malloc(sizeof(struct list));

one->data = key;

head = two;

one->next = head;
head = one;

return 0;

私は上記のプログラムの「->演算子」について覚えておらず何をどうしているのかが分かりませんでした。またoneにheadを代入して次の行ではheadにoneを代入するといった動作についても理解が及びませんでした。

 そこで一旦、arraylistの勉強はやめ、ポインタの復習をしました。ポインタはアドレスを格納するものであり、アドレスが指す先に値がある、というものでした。また「->演算子」はアロー演算子と呼ばれ左側のポインタ変数が指す先のメンバ変数を表すもの、ということが分かりました。

 このことから「struct list next」についてやっと理解することができました。「struct list next」はstruct listの先頭アドレスを格納するものである、と自分なりに解釈することができました。「one->data = key」についてもstruct listと型のポインタ変数pの中にあるdataにkeyを格納する、と解釈し理解することができました。

 しかし、「head = two; one->next = head; head = one;」の部分についてはややこしく理解することができませんでした。他にもデータを途中に追加するプログラムのサンプルコードもあったのですが、ややこしく理解することができませんでした。

 以上のことが、私が経験した中で印象に残った技術的な壁です。

(2)また、その壁を乗り越えるために取った解決法を具体的に教えてください。(例えば、知人に勧められた「○○」という書籍を読んだ)

私が共通問題2-(1)の技術的な壁を乗り越えるためにとった方法は3つあります。それは「基礎の復習をする」、「詳しい人に聞く」、「ソースコードのイメージ絵を書きながら理解する」といった3つです。

 まずは1つ目の「基礎の復習をする」です。これはポインタについてしっかりと理解できておらず曖昧な知識だったため、ポインタについて勉強し直しました。具体的には、ポインタの定義について理解し直しました。ポインタはポインタ型変数にアドレス値を格納する、というものでした。これだけでポインタについて理解し切った気になってはいけないので以下のようなサンプルコードを作成し動作についても理解しました。使用した環境は「OS X 64bit」です。

#include <stdio.h>

int main(){
    
    int num = 100;
    int *p;

    p = &num;

    printf("ポインタ*pの中身は%d\n", *p);
    printf("ポインタpの指すアドレスは%p\n", p);
    printf("ポインタ&pのアドレスは%p\n", &p);

    return 0;
}

/*
実行結果

ポインタpの中身は100
ポインタpの指すアドレスは0x7fff5e082b88
ポインタpのアドレスは0x7fff5e082b80
*/

以上の動作よりポインタはnumの値「100」を格納していることが分かります。またnumのアドレスは「0x7fff5e082b88」であり、p自体のアドレスは「0x7fff5e082b80」であることが分かります。このことよりポインタはアドレスを格納し、そのアドレスにアクセスできるものであるということが理解できました。以上のようなポインタの動作を復習するサンプルコードを実行し、ポインタについて再度理解を深めました。

 次は2つ目の「詳しい人に聞く」です。幸いなことに私のクラスには全国高専プログラミングコンテストで2位になったメンバーがいたので迷わずに聞きました。教科書のサンプルコードを見せどういった動作になっているのかを分かりやすく教えてもらいました。そこでどのようにプログラムが動作しているか大まかに分かり、大変助かりました。

 最後に3つ目の「ソースコードのイメージ絵を書きながら理解する」です。これは友人にオススメされた方法で、どこにメモリが格納されて、どういった順番になっているのか、というものを絵に起こしていくと分かりやすいと言われたことで描きました。共通問題2-(1)で分からなかった「head = two; one->next = head; head = one;」部分も絵に起こしました。そうするとこれは、先頭であるNULLを指しているheadにtwoを代入し先頭をtwoにする。oneの次を参照するnextにheadを格納、最後にheadの指す先をoneにする、という動作を表しているということが分かりました。順番に表すと「head -> one -> two -> NULL」となっています。

 以上のような方法で技術的な壁であったarraylistを乗り越えることができ、課題についても解くことができました。

(3)その壁を今経験しているであろう初心者にアドバイスをするとしたら、あなたはどんなアドバイスをしますか?

 C言語の動的配列、arraylistにつまずいてしまう人は多いと思います。実際課題を与えられた当時、自分のクラスメイトでこの課題を解いて提出している人は少なかったです。

 私はこの壁を今経験しているであろう初心者に自分がこの壁を乗り越えた方法である「基礎の復習をする」「詳しい人に聞く」「ソースコードのイメージ絵を書きながら理解する」といった3つの方法をアドバイスしたいです。3つ目の「ソースコードのイメージ絵を書きながら理解する」といった方法は少し難しいかもしれませんが「基礎の復習をする」「詳しい人に聞く」ということはできると思います。基礎であるポインタの動きについて理解していないのであればarraylistについても理解できないと思います。

 ある程度基礎がある上でサンプルコードなどを詳しい人に見せ解説してもらい、理解することも適切だと思います。プログラミングが得意な人が近くにいないならば、インターネット上で聞くことも一つの手であると思います。「聞くのは一時の恥、聞かぬは一生の恥」ですから恥ずかしがって分からないまま終わらせるより、詳しい人に聞きに行く方がより良いと思います。ここで大切なことは、最初から答えを聞きに行ってしまうのではなく、自分から努力することだと思います。最初から他力本願で答えを聞きにいくのでは、質問された側の力にはなるかもしれませんが自分の力になることはないと思います。自分でも努力した上で分からないのであれば詳しい人に聞きにいき理解することが重要だと思います。

 「ソースコードのイメージ絵を書きながら理解する」ということも重要なことです。詳しい人にアドバイスを受け自分が正しくイメージできているかを確かめてもらいます。他にもインターネットで検索すればサンプルコードと共にどういった動きをしているかについての図が載っている場合が多くあります。そこから理解を深めるのも一つの手だと思います。

 これから新しいことを学んでいく上で技術的な壁に阻まれることは多くあると思います。私はセキュリティという新しい分野を学び始めたときに技術的な壁を多く実感しました。現在も技術的な壁を感じていることはたくさんあります。技術的な壁を感じてその分野について諦めてしまう人も多くいると思います。しかし私は、諦めず根気よく勉強していくことが大切だと思います。実際、選択問題8に取り掛かったときは解答を得るまでに3週間以上もかかり、何度も挫けそうになりました。その度に共通問題2-(2)で示した3つのことを実践し一つ一つ理解し解いていきました。そして問題の解答を得たときにはかなりの達成感を得ることができました。これはarraylistの課題を解き終わったときも感じました。さらに選択問題8を解き終わったときには達成感とともに、アセンブリに対して非常に興味が湧いてきました。これはあくまで自分の例ですが、もし技術的な壁を感じてもそれを乗り越えることができたとき、その分野や技術に興味を持ち、そこで光るものが出てくるかもしれません。

 なので私は諦めず努力をすること、今回の場合でいうと具体的には「基礎の復習をする」「友人に聞く」「ソースコードのイメージ絵を書きながら理解する」といった3点を技術的な壁を今感じている初心者にアドバイスしたいです。

共通問題3

(1)あなたが今年のセキュリティ・キャンプで受講したいと思っている講義は何ですか?(複数可)そこで、どのようなことを学びたいですか?なぜそれを学びたいのですか?

 興味を惹かれるものがいくつもあり様々な知識を学びたいと思いました。中でも興味のある実地される7つの講義を選びました。

 1つ目は「Dissecting Malware - x86 Windows malware analysis -」です。セキュリティの勉強自体は最近始めたのですが、一番初めにセキュリティと聞いて真っ先に思い浮かんだのがマルウェアの解析でした。実際、セキュリティはWebアプリやサーバなど様々なところで応用され想像してした以上の種類がありとても面白い分野であることが分かりました。マルウェアの解析について興味はあったのですが一人で勉強するのには危険なイメージがあり、やり方も全く分かりませんでした。この講義ではそんなマルウェア解析ができ、それに対する有用なマルウェア対策を学べるということで心から受けたいと思います。またマルウェア解析の手段として逆アセンブルコードをひたすら読み解き学べるとあります。選択問題8を解いて逆アセンブルコードの解析を行いプログラムがどのように動いているのかパズルゲームを解く感覚でできることに楽しさを知りました。ですのでこの講義内容に興味を持ち非常に楽しみです。この講義で必要な知識を身につけ、悪質なマルウェアを失くし、安全にアプリケーションを使用できる環境にしていきたいです。

 2つ目は「人工知能とセキュリティ」です。近年人工知能という言葉を多く耳にするようになりました。AlphaGoやりんな、Tay、Watsonなどの人工知能に関する話題やニュースを多く見かけます。ですが人口知能に関する話題やニュースで見かけるのは性能や仕様、活用方法などばかりでセキュリティに関することは聞いたことがありません。人工知能の安全についての話題は全く見かけたことがないので疑問を持っていました。人工知能のセキュリティ面はあまり危険視されず思想が危ぶまれています。最近ではTayがヒトラーの思想を肯定するような発言をして波紋を広げました。人工知能の話題が次々と出てくる中、前々から人工知能のという分野もさることながら人工知能のセキュリティについて大変興味を持っていました。この講義ではそんな人工知能のセキュリティを取り扱うということでどのような攻撃手法があり、それに対する防御方法について学びたいです。

 3つ目は「The OOM CTF」です。普段学校やサーバなどで使用されるLinuxにOut of memory local DoS 攻撃が通る脆弱性が存在し、まして簡単に成立することを初めて知りました。Linuxカーネル内のメモリの管理機構が楽観的に作られていると書いてありますがどのように管理機構になっていて、なぜこのような脆弱性が存在するのかについて興味があります。この講義を通してメモリ枯渇に起因したバグハンティングの技術を身につけどのようにしたら安定してLinuxが稼働するのか、この脆弱性はどれくらい無くせるのかを知りたいです。

 4つ目は「オンラインゲームアタック&ディフェンスチャレンジ」です。オンラインゲームは私もたまにプレイします。そこでは不正行為とされるチートなどを何度か見かけることがありました。不正行為をしてアカウントを抹消される、などはよく聞く話です。ただ、不正行為をするアカウントをいくら消しても不正行為自体は無くなりません。この講義では運営側と攻撃側に分かれゲームをするような形式でどちらかの視点も学べるとありとても楽しみです。私は攻撃側にまわりどのようなパラメータが渡れば運営者が嫌がり不正行為になるのかについて学びたいです。この講義が終わった後攻撃者側の視点だけで終わるのではなく、運営側を担当した人とディスカッションし守るときにどのような視点から攻撃を阻止したのかを聞き守る側の知識も学びたいです。こういった不正行為はオンラインゲームだけに止まらずWebアプリケーション、Webサイトでも存在すると思います。ここで学んだ知識をオンラインゲームだけでなく広い視野を持って役立てたいです。

 5つ目は「みんなでクールなROPガジェットを探そうぜ」です。この講義をHPで見たときに初めてROPというものについて知りました。調べてみるとROPはプログラムを拝借して、そのコードを組み替え、悪意のある動作をさせるように、コードを作り変えることの総称であることが分かりました。これを講義では「自作し利用する技術が学べる」とありとても楽しみです。そしてアセンブリを読むと思うのでアセンブリに興味がある自分にとっては楽しみでしかたありません。またROPが脆弱性となるのか、悪意のない動作にさせたらセキュリティホールを埋められるのかなども学びたいです。

 6つ目は「リバースエンジニアリングを自動化せよ」です。私は逆アセンブルを手動で解析する方法しか知らず、脆弱性発見やマルウェア解析はもちろん手動でなければ解析できないと思っていました。なのでこの講義内容を見たときは目からウロコでした。驚いたと同時にどうやってリバースエンジニアリングを自動化するのか、手動と比べどれくらい早く解析できるのか、精度はどのくらいなのか、どのようなレベルまで解析が可能なのか、といった様々な疑問が浮き上がってきました。このような疑問を講義で解決しリバースエンジニアリングの自動化の方法と有用性などを学びマルウェア対策の技術を学びたいです。

 7つ目は「遠隔操作マルウェアと標的型攻撃からの防衛」です。この講義をHPで見たときマルウェアのシミュレータがあることを初めて知りとても驚きました。このシミュレータを通してマルウェアの動作原理について理解しどのような攻撃がされるか、どういったセキュリティホールをついた攻撃なのかを学びたいです。対策をしても破られていくといった体験は中々できるものではないと思うのでとても楽しみです。他の講義で学んだ検知方法の手段から検知回避のリスクについての考察をし、講義を受けた人同士でディスカッションし合い様々なリスクについて自分とは違った見方なども学びたいです。

 以上の7つが私の受けたい講義です。しかし、受けたい講義は他にもたくさんあり、時間が重複してしまい受けられず体が1つしかないのを悔やんでいます。これらの講義から様々な角度からのセキュリティについて学び、セキュリティ対策がしっかり行えるように知識を身に付けたいです。

(2)あなたがセキュリティ・キャンプでやりたいことは何ですか?身につけたいものは何ですか?(複数可)自由に答えてください。

私の学校でセキュリティに携わる先生がセキュリティ学習のカリキュラムを始めるということで、セキュリティという分野に興味を抱き勉強し始めました。まだ勉強を始めて日が浅く自身のセキュリティに関する技術がまだまだ足りないと思っています。そんな中、先日行われた「セキュリティ・ミニキャンプ in 香川」を勧められ、気になったため応募し参加しました。そこで学んだHTTPプロキシや光ファイバケーブルからの盗聴技術がとても面白く興味を惹かれるものでした。セキュリティ・ミニキャンプで学んだこと以外にもセキュリティについてもっと詳しく勉強したいと思いました。そして、さらに深くセキュリティについて知り、今後セキュリティに関わっていきたいと強く思いました。こういった経緯から今回のセキュリティ・キャンプに応募しました。

 セキュリティ・キャンプを通じて高いレイヤーから低いレイヤーにかけて様々な知識を吸収したいと考えています。特に低いレイヤーに関しては選択問題8を解いて初めて逆アセンブルコードを読み解きました。そこで解析の面白さを実感し、他の解析の方法について深く学びたいと思いました。選択問題8を解いたことで、解析に関してとてもモチベーションが高くなっています。今まで私は高いレイヤーのことを多く扱っており、低いレイヤーのことをないがしろにしがちでした。ですのでセキュリティ・キャンプでは解析トラックの講義を多く受講したいと考えています。解析トラックの講義は様々な部分の解析ができるので、数々の解析方法を学べると思うと今から胸が高鳴ります。低レイヤーの技術は学校の授業ではあまり扱わないので、様々な技術を吸収し身につけたいです。

 知識・技術を深めるだけでなく、セキュリティ・キャンプに参加している他の参加者とグループワークなどを通じて交流を深め、議論を交わしたいと思っています。同じ志を持った方々と意見が交わせるのはとても貴重な体験になり、モチベーションにもなると思います。また講師の方からも話を伺い、セキュリティの世界が今どうなっているか、セキュリティという分野が今後どのように進化していくべきなのか、などセキュリティに関する様々なことを聞きたいと思っています。

 ここで身につけた知識・技術は今後の卒業研究に絡めたいと考えています。また、学んだセキュリティの技術を生かして「SECCON」、「CTF for Beginners」、「危機管理コンテスト」などへの参加もしたいと考えています。そしてセキュリティ・キャンプの修了生として、「セキュリティ・キャンプ」、「セキュリティ・ミニキャンプ」のチューターとしての活動をしたいです。それを通じてセキュリティの大切さ、面白さを次の参加者に伝えていく活動をしたいと思っています。

 以上が私のセキュリティ・キャンプに参加し身につけたいことです。


 こんな感じに書きました。見て分かる通り、共通問題2-(2)は友達に添削してもらったのですが直してない&添削が残ったまま提出してしまいました(笑)これが功を奏したのか否なのか・・・

 自分は技術的な面においてあまりにも弱かったので頑張って熱意を書きました。

 選択問題についても別で書きます。

 Markdown難しいですね・・・。罫線の後に文字書くとその前の文字太くなっちゃうんだけどどうしたらいいんだろう。