Senchaのブログ

あまり更新しません

クラスター入社1年エントリ

こんにちはSenchaです。
クラスターに入社して1年たったということで、エントリを書いていこうかなと思います。

クラスターの詳しい会社紹介はこちら。

speakerdeck.com

前半は入社前後のことを思い出しつつ、ほぼ入社エントリ的なものを、後半は1年経ってみて感じたことを記していきます。


Sencha (@konnich18757474) / Twitter です、インテリアと麻雀が好きなUnityエンジニアです。

ちょうど1年前、2022年の8月にクラスターに入社しました。
前職は新卒で入社したゲーム会社で小さいゲームを作ってはテストし、作ってはテストし、みたいな日常を送っていました。

分かる人には、何をやっていたか察しがつきそうですね。


なぜクラスター?

前提として、転職時自分は以下のことを叶えたいと思っていました。

  • そこそこ大きいプロダクトでチーム開発ができ、技術的に成長できる
  • 自分が今まで作っていた小さいゲームとは違った新しい体験を作りたかった

Unityエンジニア == ゲームを作る、だった自分にとっては新しい道を切り開けそうと感じたのが正にクラスターだったのです。

  • そこそこ大きいプロダクトでチーム開発ができ、技術的に成長できる

これまでチーム開発をほとんど経験してこなかったため、最も重要視していた条件でした。 前述にもある通り前職では小さいゲームを作っており、そのほとんどを1人で開発していました。
もちろん企画から自分で考え、デザインもUnityAssetを使い安価に…自分で考え自分で作れるというものはとても楽しかった反面、どうしても技術的に向上していく実感が湧きませんでした。(1人で作っているので基本コードレビューなどもほとんどない状態)こんな状況が逆に珍しいかも、というのは一旦置いておきつつ…。

その点、クラスターでは1つのプロダクトで複数の領域に跨って開発しています。Unityエンジニアだけでも数十人程度の規模で開発しており、求めていたチーム開発が行えそうでした。
クラスターではTechBlogも積極的に書かれており、プロダクトをどのように作り上げているかや使用されている技術が事前に分かり、自身の技術的な成長にも繋がるだろうと感じました。

tech-blog.cluster.mu

  • 自分が今まで作っていた小さいゲームとは違った新しい体験を作りたかった

前職では自分で企画から行っており、今のヒットゲームにはない目新しく面白いと感じる体験 ≒ ゲーム性を常に考えていました。そんな折に感じていたのが、「ゲームとは違った別の体験を届けられるようなものに携わりたい」ということでした。とはいえ、この時点で自分の技術スタックでどういったものができるのかはあまり検討がついていませんでした。

クラスターから話を受けたときは、「メタバース、そんなものもあるのか〜面白そうやな」と感じたのを覚えています。お恥ずかしい話、話を聞く前はクラスターはおろかメタバースについてもほとんど知識がありませんでした。
そこから代表の加藤さんのインタビュー記事を読み漁ったり、本を読んでいく中でクラスターが目指している未来や提供しようとしている体験に共感しクラスターに決めました。


1年経ってみて

さて、そんなこんなで気づいたら1年経っていたわけですが、実際に1年働いてみて以下のようなことを感じています。

  • 技術的に成長できている!(...多分、ですよね?)

入社当初の自分のスキルとしては、Unityを扱うことはできるが個々のフレームワーク(UniRx, UniTask, Zenject…)にはかなり不安があり、アーキテクチャなどはさっぱり…といった状態でした。
そのような状態から初めはチームや、他のエンジニアのサポートなどを受けつつ、次第にプロダクトにコミットできるようになり、epic ownerも任せてもらえるようになり(※ epic ownerについては後述)…なんとかなるものですね。

社内ではコードレビューも良い感じに行われています。最近だとレビューワーとして自信を持ってアプルーブできない場合に、「レ助〜(レビュー助けて)」とSlackで呼びかけることによって、その領域に自信のある人にサポートを貰いつつコードレビューを進めることができます。
レ助文化により、自身の領域理解を深めつつ、レビューの信頼度も上げることができるのは非常に助かります。

個人的には入社当時と比べると技術的にかなり成長できたと実感しています。

  • epicの進行は面白い

クラスターではepicと呼ばれる開発フローが採用されています。epicの詳しい説明はこちらからご覧ください。

tech-blog.cluster.mu

開発中の進行管理や、リリースに対する責任がepic ownerに発生します。epic ownerには責任感もありますが、任せてもらえているという実感もあり、自分が手がけたものが世に出たときにはやりがいを感じます。その都度振り返りを実施し、次に繋げたり社内に共有できるのもいい文化ですよね。

  • リモートって働きやすい

クラスターは月1回出社のリモート中心の会社です。そのため、主なコミュニケーション手段としてSlackを利用しています。社内ではSlackがとても活発で、プロダクトの話はもちろん雑談なども日々気軽に行われています。
そのためリモートであっても孤独感は全くなく、何かしら投稿すればすぐリアクション等貰えます。mtgなど、仕事の進め方も体系化されており、家にいながら出勤しているかのような距離感で仕事ができていると感じます。

tech-blog.cluster.mu

  • 麻雀部

完全に余談ですが、クラスターには部活動が存在します。
最近では社内の活動に留まらず、麻雀企業対抗戦というものにも出場中です。

絶賛部員募集中!!


終わりに

いかがでしたか?これからの麻雀部の活動にご期待ください!

…とまあ、麻雀部の話は置いておいて、ここまで長々と読んでいただきありがとうございます。
総括として、クラスターで1年働いて率直に「とても面白い、楽しい!」と感じています。
この記事でクラスターに少しでも興味を持っていただけたら幸いです。

採用はこちらへ

recruit.cluster.mu

エンジニアの方はこちら

recruit.cluster.mu

セキュリティ・キャンプ2016に参加してきたのでその感想

タイトル通りセキュリティキャンプ2016が無事終わったのでその感想を・・・。

どんな講義をやったかについては他の参加者がたくさん書いてくれていると思うのでここでは自分なりの感想とどんな人がセキュリティキャンプに参加すべきかみたいなこと書きたいと思います。あくまで個人の感想ですので

感想

まずはそれぞれの感想を。


講義について

自分は1-D、2-B、3-D、4-D、5-D、6-D、7-Bを受講しました。

各講義の概要はセキュリティキャンプ実地協議会のHPに載っています。

受講した感想といたしましては、まあ分からなかったですね。全部分かりませんでしたし、各講義でこなさなければならないタスクのノルマを達成できたのは1つ2つくらいしかありませんでした。

講義が終わった後毎回鬱になりましたね。自分はほとんど何をしているか分からない、何をすればいいか分からない状態だったのに対し、周りの参加者はどんどん解いて先に進んで行く。そんな状況で進捗を全くあげれてなかったのでとても悔しかったです。

ここで痛感したのは皆さん本当にこの分野が好きなんだな〜ということでした。趣味でアプリケーション作ってたり、サーバー構築したり、CTFしてたりする人に比べ絶対に勝てないことを悟りました。

この分野嫌いではないのですが自分から何か作ったり、問題を解いたりすることはどうしてもやる気になれず、せいぜいやっても学校の課題をこなすくらいなものでした。

そんなこんなで講義が分からない、解けない状態だったのであまり楽しくなかったです。


CTFについて

各グループの中で最後まで0点だったので完全に鬱でした。


企業の説明聞きに行くイベント

これは楽しかったです。色々な話が聞けました。仕事の内容から、プライベートなことまで話してくださってとてもためになりました。


グループワーク

4つの

・「10年後のIT社会のセキュリティのあるべき姿」

・「子供たちに正しくIT技術を身につけさせるために」

・「小規模企業におけるセキュリティ対策」

・「攻撃者に狙われないために何をすればいいか」

といったテーマがあって各班がそれぞれ選択したものに対し発表するって感じでした。

自分たちの班は「子供たちに正しくIT技術を身につけさせるために」を選択しました。

これも楽しかったです。正直一番楽しかったです。複数人が同じ目標を持って進んでいくって良いですよね。

あまり技術的な要因は必要としなくて考えれば分かることだったので講義に比べてとても楽でした。

自分はこういった哲学チックなことを考察するのが好きで原稿的には結構まとまってそこまでは良い出来だと思いましたねー。

全部のテーマやりたかったです。


セキュリティ・キャンプにはどんな人材が参加すべきか?

今回最も伝えたい部分はここです。

セキュリティ・キャンプはあまり知識はなくても熱意があれば大丈夫!!!とか言われてますけどそんなことはないです。知識は圧倒的に必要です。

まず講義についていけなさすぎて鬱になります。基本部分ができていないのにその上の応用部分をやっているので、講義から学びたい・吸収したいものがあるなら基礎知識は最低でも身につけるべきだと感じました。

次に同じ参加者とコミュニケーションがあまり取れなくなります。参加者同士で話す内容は自分の好きな分野のことや、どんなことをやっているかについてなのであまりにも自分が何もやってないと話についていけずご飯の時とか話すことなくなります。

こんな感じで知識も全くない状態で参加したので、ほとんど講義も分からず、さらには同じ参加者とあまり話せませんでした・・・。

そして何よりこのセキュリティ・キャンプに参加すべき人材はこの分野が本当に好きで、自らどんどん学んでいく力がある人だと思います。

この点に関して何よりも他の誰よりも劣っていました。

前にも書いたようにこの分野嫌いではないのですが、熱中するほどではないので本当に好きな人には絶対勝てないと思っています。セキュリティ・キャンプに参加したいと思っている人、本当に自分は情報という分野が好きなのかというのを今一度考え直して参加するかどうか決めた方がいいと思います。


セキュリティ・キャンプを通して

何もできなかった自分ですがセキュキャンに参加したおかげで色々なことを考えさせられました。このままなぁなぁに続けても絶対に成長しないと感じてしまったので自分はエンジニアになることは辞めようかな〜とか思ってます。

というのも企業さんの話を聞いて、グループワークを通して何かを伝えていったりする活動もとってもいいなって思い始めたからです。特に企業さんの営業の方の話を聞いて自分の仕事が楽しくて誇りになっているんだなーって伝わってきました。そんなこんなで具体的にはセキュリティを売る技術営業やりたいって感じですね。

前々から人と喋るのが好きなので、人と関わり・ためになるような仕事をしたいです。

だからといってセキュリティの勉強をやめるわけではなく、これからはそれも触りつつ英語とか勉強してスキルをつけていこうって思っています。


セキュリティ・キャンプを終えて

辛いことが多くあったんですけど、途中でめちゃめちゃ話の合うオタクが一人と鬱病仲間が一人できたので結構助けられました。

結果的には得るものが多くあって自分の考えとか結構変わって良かったです。

教材たくさん貰えたのも嬉しかった(勉強するかは分からない)。ご飯も美味しかったしね!


終わりです。結構思ったまま文章にしているんで変なところがあるかもしれません。他にも言いたいことが文章にまとまったら追加しようと思ってます。ブログ読んだ感想とか是非ください。

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

 次、選択問題について書きます。あまり知識がないので考えれば書ける問題をできる限り多く取り組みました。結果的に3、6、7、8、9の計5つ解きました。

選択問題3:RAMは主記憶装置、HDDやSSDなどは補助記憶装置と呼ばれます。一般にCPUは主記憶装置上のプログラムしか実行できません。ではなぜ、私たちは普段から補助記憶装置に書き込んだプログラムを実行できているのでしょうか?パソコンの電源を入れてからのストーリーを考えてみてください。

 プログラムを動かす上でCPUはHDDやSSDなどの補助記憶装置から(は)実行できません。しかし、OS自体もHDDやSSDの補助記憶装置に書き込まれているため、どのように起動するのかについて疑問を持ちました。データを処理するのがCPUであるため、メモリからデータを渡されないとOSは起動できません。OSをメモリにロードするためにはメモリにあらかじめ存在してなくてはならないと考え、矛盾が生じてしまうと思いました。

 以下にパソコンがどのようにしてOSを起動するかについてのストーリーと、補助記憶装置上のプログラムがどのように実行されるかについてのストーリーを示します。

 まずはパソコンが起動する流れです。

1:パソコンに電源を入れるとまず始めにROM(Read Only Memory)に記録されている第1次ブートローダであるBIOS(Basic Input Output System)が直接起動します。

2:BIOS自信はOSを起動するのに十分な機能がないため、OSを読み込むのに使用するプログラムである第2次ブートローダを読み込みます。WindowsではBOOTMGR、LinuxではSYSLINUXです。

3:第2次ブートローダはハードディスクからOSを起動するのに必要なプログラムを次々とRAM(Random Access Memory)にロードするように命令を出し、一定段階ロードすると残りはOS自身がロードを行い起動します。

 以上の動作によってOSが起動し、パソコンが使用できるようになります。メモリ上に存在しないOSが起動するのは、第1次ブートローダであるBIOSと第2次ブートローダのおかげだということを知り、矛盾しないことが分かりました。

 次は補助記憶装置上のプログラムがどのように実行されるかについてです。私たちは普段プログラムの実行を簡単に行ってしまい、その裏でどういった動作が行われているかについてあまり考えることはありません。HDDやSSDなどの補助記憶装置上のプログラムをどのようにしてCPUがプログラムを実行しているかについては以下の通りです。ここでは「Hello, World」と表示するプログラム「a.out」を実行したとします。

1:実行ファイルを「./a.out」といった形式で入力し、実行するとI/O命令が出され、割り込み要求が発生します。割り込み要求を受け取ったCPUは割り込み要求を処理します。その処理方法はOSに任されます。

2:OSから命令が出され補助記憶装置上にある「a.out」の機械語を丸々RAMにコピーします。

3:RAMにコピーされたプログラムの指示に従い、CPUが動作します。その動作は以下の通りです。

3.1:CPUがRAMから命令を取り出します。命令を取り出すアドレスはCPUのプログラムカウンタに書かれています。

3.2:取り出された命令はCPU内の命令デコーダにより、命令内容を解析します。

 3.3:解析された命令は論理演算装置によって演算が実行されます。

 3.4:演算結果は各種のレジスタに格納されます。

 3.5:プログラムカウンタの値を再設定します。

 3.6:以上の動作をプログラム終了まで繰り返します。

4:メモリマップドI/Oによって出力結果である「Hello, World」が画面に表示 されます。

以上が補助記憶装置上のプログラムが実行されるストーリーです。

 しかし、分からないことが1つありました。出力結果を表示するのには処理を追っていくとシステムコールが命令されます。私はシステムコールが上記の手順のうちどのタイミングで命令されるのかが分かりませんでした。

 私は普段どのようにOSが起動しているのか特に考えずパソコンの電源を入れ操作します。そしてどのようにして動いているのかもよく知らないまま補助記憶装置上のプログラムを実行していました。この課題を通していかに自分が低レイヤーの働きについて蔑ろにしていたかを痛感しました。それと同時にOSの起動がどのように行われ、プログラムがどのように行われてるかについて興味を持ち、詳しい処理内容がどのようになっているかについて知りたいと思いました。

 またOSがどのように起動しているかについて理解し、興味が出たと同時にどのようにしてシャットダウンしているのかについて疑問を持ちました。ですので、以下にどのようにしてOSがシャットダウンするのかについてのストーリーも示します。

 1:マウスを操作しシャットダウンボタンを押すと割り込み命令が発生します。

 2:OSがシャットダウン処理を開始します。

 3:初めにアプリケーションが終了されます。

 4:次にバックグラウンドで動作するプロセスが終了します。

 5:その次に各種マネージャーを終了します。このとき構成マネージャーはレジストリをディスクに保存し、メモリマネージャーはキャッシュに保存されているデータが正しく反映されているかチェックします。

 6:最後に全てが終了すると処理を終了し、電源をオフにしてシャットダウンが完了します。

 以上がシャットダウンまでの流れです。大まかなシャットダウンプロセスは分かったのですが細かいメモリやOSの処理までは分かりませんでした。起動プロセスやプログラムの実行までの流れだけでなく、シャットダウンの詳しい動作についても知りたいと思いました。

 アプリケーションなどを開発するときに低レイヤーの働きを知っていることはバグ取りや応用にも繋がると思うのでもっと深く勉強し、高レイヤーだけでなく低レイヤーの働きも理解しているエンジニアになりたいです。

選択問題6:IDとパスワードを入力してユーザの認証を行うWebアプリがあります。あなたがこのアプリに対してセキュリティテストを行う場合、まず、どのようなテストをしますか?なぜそのテストを選択したのか、その背景や技術的根拠と共に記載してください。アプリの内部で使われている技術やシステム構成に、前提を置いても構いません。

 Webアプリケーションに対して私はまず初めに以下の7つの項目の脆弱性をつくことによってセキュリティテストを行いたいと考えます。しかし、これだけを行っていれば安全というわけではないことに注意しなくてはなりません。

1:SQLインジェクション

2:OSコマンドインジェクション

3:ディレクトリトラサーバル

4:セッション管理の不備

5:クロスサイトスクリプティング

6:クリックジャンキング

7:バッファオーバーフロー

 なぜ上記の7つのセキュリティテストを選択したかというと、私はIDとパスワードを入力する形式のWebアプリケーションにおいていずれも重要であり、当たり前に対策できているべき脆弱性であると考えたからです。また当たり前に対処できている基本中の基本であるからこそ忘れがちになっていると考えられます。これらの脆弱性は一つでもあるとWebアプリケーション上にある個人情報や運営機密などを盗まれ悪用されてしまう恐れがあります。またこれらの基本的な脆弱性対策が一つでも欠けていると、セキュリティに疎い開発者だと思われもっと高度な攻撃や別の目的を持った攻撃も受ける羽目になるかもしれません。個人情報の漏洩だけでなくWebアプリケーションサービスの停止などにも繋がってしまう恐れもあります。

 ここで1つSQLインジェクションの例をあげます。SQLインジェクション攻撃は非常に簡単に行うことができます。実際に私がCTFでSQLインジェクション脆弱性をつく問題に取り組むとき、SQLインジェクションという言葉さえ知りませんでした。しかしインターネットで調べるとSQLインジェクションという攻撃方法があることをすぐ見つけることができました。そして、その方法もすぐに分かり簡単に攻撃することができました。

 IDとパスワードを入力するWebアプリケーションだとユーザの管理はデータベースで行っていると考えられます。このとき適切な処理を施していないと不正なSQL文が実行され悪意のあるリクエストによりデータベース上の個人情報が流出してしまう可能性があります。

以下に示すSQL文を用いたログイン判定には脆弱性があります。

SELECT * FROM user WHERE uid='$uid' AND pwd='$pwd'

この場合「' OR 1=1--」という文がパスワードに与えられたとき、不正ログインを可能としてしまいます。この対策としてはエスケープ処理を施すことで対処することができます。他の対策としては、プレースホルダを実装する、渡されるパラメータにSQL文を指定しないなどの方法もあります。

 ここでは不正ログインだけでしたが、情報を盗み出すようなSQL文が実行されれば多くの個人情報が流出します。ここで流出したデータが悪質な業者に売買され、不正に使用しようされてしまうようなことがあれば、被害はさらに拡大してしまいます。

 ですがこのような対策をせずともSQLインジェクションや、クロスサイトスクリプティングは使用しているWebアプリケーションプラットフォームがApache StrutsRuby On Railsであれば元々作りこまないように設計されており、セキュリティ対策が施されています。このように開発者がソースコードを書く際に気を配らなくても対策を行えます。

 しかし上記で挙げた脆弱性の他にもCSRFやHTTPヘッダインジェクション、メールヘッダインジェクションなど様々な脆弱性が存在します。開発者自身が知らない脆弱性も潜んでいるかもしれません。セキュアなWebアプリケーションを提供したいなら脆弱性を発見してくれるツールやバグハンターのような専門の方に任せて探してもらうという手段もあると思います。重大な脆弱性がなくとも小さな脆弱性から大きな問題に繋がってしまう可能性もあります。インターネット上で提供する以上100%安全なアプリケーションは存在しないと思います。個人情報を扱う以上開発者は常にセキュリティについて気を配るべきだと考えます。

 以上がWebアプリケーションに対して7つのセキュリティ対策を行う理由です。しかしこれらのセキュリティ対策だけではセキュアなアプリケーションとはいえず、他の脆弱性も存在すると思います。

 残念ながら私はWebアプリケーションを本格的に作成したことがなく、脆弱性自体は知っていても対策の方法が分からないことや、知らない脆弱性自体も多くありました。いずれは私もWebアプリケーションを作成しインターネット上で提供してみたいと考えています。そのときに脆弱性が存在するようなアプリケーションを提供することがないよう、セキュリティ・キャンプで脆弱性の評価・対策を学びセキュアなアプリケーションを提供したいです。

選択問題7:あなたが管理するネットワークに悪意ある第三者が存在しない事を証明する方法を思いつく限り列挙してください。なお、条件として物理的にアクセスされる可能性を想定してください。

 悪意のある第三者が存在することを証明することは不可能だと思ったので悪意のある第三者が存在しうるであろう部分の可能性を考えます。そこを潰していくことによって悪意のある第3者が限りなく存在できない環境にしていきます。

 まずはPCに直接繋げられている場合を考えます。このような場合にはCPU時間や、アクティブで動いているメモリを確認し安定した状態をある程度定めておきます。その範囲を超える異常な動作が見られれば第三者が存在する可能性が出てきます。PCのユーザ数を確認し、自分の知らないIPアドレスMACアドレスがあった場合には悪意のある第三者が存在するかもしれません。また、見覚えのないコマンドログやエラーログ、アクセスログなどが残っていれば侵入された可能性が浮上します。他にも、元あったデータと比べてデータを抜き取られていないか、壊されていないかを確認します。データが無くなっていたり壊れていたりしたら悪意のある第三者が存在する可能性が出てきます。

 ルータにシリアルケーブルなどで直接接続されている場合にはルーティングテーブルが書き換えられていないか、インタフェースに見覚えのないIPアドレスなどが振られていないかを確認し、見覚えのないものが見つかったら悪意のある第三者が存在している可能性があります。

 サーバも同様にポートや、ユーザ数、ログ、機器の温度を確認し、悪意のある第三者が存在している場合は異常を発見できます。

 特殊な例だとは思いますが「セキュリティミニキャンプ in 香川」で光ファイバケーブルからの盗聴について講義を受けました。そこでは専用線クロージャーの上でカプラを繋ぎスプリッタで光を50:50に分割し一つを正常な方向へ、もう一つは盗聴側へ回しコンバータでイーサネットから盗聴することができるというものでした。私が「光ファイバケーブルから盗聴を行われていた場合にPCから確認できるのか」と講師に質問したところ「基本的には無理である。しかし、デシベルの状態を常に見ていて光ファイバケーブルが切られたとき僅かにデシベルが下がるので、そこで異常を検知できればわかる」と返答をもらいました。このようにして常に見張っていれば光ファイバから盗聴されているかそうでないかを考えられます。

 また悪意のある第三者が存在できるであろう電子機器も幾つか考えられます。しかし以下に示すのは自分ではどのように接続されていて、どのように悪意のある第三者が存在しているのかが分かりませんでした。

 ネットワークに繋がったプリンタなどの電子機器も十分悪意のある第三者が接続可能であると考えられます。近年電子機器がネットワークに接続されることが多くなってきました。冷蔵庫もネットワークに繋がるようになり冷蔵庫から悪意のある第三者が侵入してきてしまう可能性も考えられます。電話線に繋いで盗聴される、電源から盗聴される、電磁波から盗聴されるといった可能性も考えられます。

 この問題を解くに当たって様々な方法を考えました。しかし、完璧にネットワークに悪意のある第三者が存在しないことを証明不可能だということが分かりました。そこで存在する可能性がある部分を潰していくことで存在しない可能性を高めていきました。高いレイヤでの証明ならまだしも、光ファイバからの盗聴のように低いレイヤまで考えると検知、発見する方法が限られてきてしまいます。さらに自分の知識では分からないものもあり、いかにこの問題が難しいかを実感しました。自分の少ない知識でもこれだけの項目を上げることができました。セキュリティを行うことがいかに大切か、どこまでのレベルでセキュリティを上げていき、どういった項目までセキュリティ対策をしなくてはならないのかということについて深く考えさせられました。あらゆる角度からどのような攻撃がくるかということを考えネットワークを構築していくことが大切だと感じました。

 この証明がどれくらいできるのか、どういったレベルまでセキュリティを施しても侵入が可能なのか、などをセキュリティキャンプに行って学び、自分がネットワークを構築するときにセキュアな構築ができるようになりたいです。

選択問題8:以下のダンプはあるプログラムのobjdumpの結果である。このプログラムが行っていることを調べ、その結果を記述してください。完全には分からなくても構いませんので、理解できたところまでの情報や調査の過程で使ったツール、感じたこと等について記述してください。

 この結果を手動で解析したところ、標準入力から文字列を受け付け、「c@Np2O16」だったら正常に終了を、そうでない文字列が入力されたら異常終了をするプログラムだと分かりました。ダンプ結果の動作は以下の通りです。

 まずpushq命令によって値を次々にスタック上に積まれるので一つ一つ紙に書いて積んでいきました。

 途中にある「movabs $0x63391a67251b1536, %rax」は%raxに第一オペランドの値を絶対値で格納しています。ここでmov命令ではなくmovabs命令を使ったのはmov命令だと値が入りきらないからだと考えました。

 スタックを積み終わると「retq」という命令がありますが、これはスタックポインタが指している値に返るという命令です。なのでこの場合には「retq 0x400102」の番地へ飛びます。ダンプの結果を見るとretq命令が多く、様々な番地へ飛ぶプログラムだということが考えられます。

 0x400102へ飛ぶとpop命令によって%raxに0x0を格納します。 pop命令はスタックポインタが指す値をレジスタに格納するという命令です。

 「retq 0x400106」へ飛ぶとpop命令により%rdiレジスタに0x0を格納します。

 「retq 0x40011c」より「mov %rsp,%rsi」の番地に飛びスタックポインタが指す値、0x40011cを%rsiレジスタに格納。またretqしていき、pop命令により%r10に0x0を、%rdxに0x8を格納しました。

 次に「retq 0x400119」により「syscall」が呼ばれます。この時、システムコール番号である%raxには0が格納されているのでシステムコールテーブルより「read」が呼ばれることが分かります。第1引数%rdi = 0、第2引数%rsi = 0x40011c、第3引数%rdx = 8より標準入力からテキスト領域である0x40011cに8byte分の文字が入力を受け付ることが分ります。

 「retq 0x400108」のpop命令により%rbpに0xffffffffffffffe0が入リます。「0xffffffffffffffe0」は一見とても大きい値に見えますが、隣の機械語の命令を見ると値の割に機械語の命令の数がとても少ないことが分かります。調べてみるとこれは2の補数表現によってマイナスの値であることがわかりました。

 retqされpop命令が呼ばれ%rcxに7を格納。「retq 0x400114」に飛ぶとxorb命令、「xorb $0x55,(%rsi,%rcx,1)」呼ばれます。この命令は$0x55%rsi + 7 * 1という意味であり、%rsiの値、つまり標準入力から受け付けた文字列を7byte、0x55で排他的論理和をしています。

 「retq 0x400129」により「dec %rcx」が呼ばれ%rcxは7 ー 1より6となりました。次は「jne 0x40012c」という命令がきており、jneは直前の演算の結果が0ならばjmpしない、0以外ならjmpするという命令なので今回は0x40012c番地に飛びます。

 jne命令でjmpし「pop %r10」が呼ばれ、この時のスタックの値0x400102が入ります。

「retq 0x40010c」により「add %rbp,%rsp」が呼ばれます。%rspに%rbpの値が加算されますが%rbpにはマイナスの値が入っています。0xe0の2の補数表現の値は「0010 0000」となり-40bit、つまり-5byteとなります。%rspはスタックに積まれている先頭の値を指すのでこれが書き変わるということはretq命令で呼ばれた場合に本来とは違う場所に飛ぶことになります。%rspは現在0x40010cを指しており、そこから-5byte分スタックに積まれていた値を遡ると0x40010aであり、retq命令によってこの番地に飛ぶことになります。

 0x40010a番地に飛ぶと「pop %rcx」により0x7がまた格納されるように見えますが、ここの値はすでに保持しておらず何もされません。そのため演算や、retqなどの命令はできますがpop命令は意味をなしません。

 「retq 400114」により「xorb $0x55,(%rsi, %rcx,1)」、%rcxの値は6なので6byte排他的論理和がされます。

 「retq 400126」により「dec %rcx」が命令され6 ー 1 = 5となります。

 先ほどのjne命令は0になったら飛ばなくなるので、この%rcxの値が0になるまでループすることが分かります。「xorb」命令が途中に入るので5,4,3,2,1の順で排他的論理話がされることが分かります。

 %rcxの値が1まで行くと「dec %rcx」により1 ー 1 = 0。「jne 0x400102」が呼ばれますが直前の演算が0になったので飛ばずにループを抜け出します。

 「pop %rax」により%raxには0x40010cが格納されます。

 「retq 0x400114」により「xorb $0x55,(%rsi, %rcx,1)」が命令されます。%rsiには標準入力から入力された8byteのデータが入っていますが、xorbの命令で排他的論理和されていたのは7byte目までです。しかしここで8byte目の値も$0x55で排他的論理和されます。

 「retq 0x400106」により「pop %rdi」には0x0が格納されます。 

 「retq 0x400102」により「pop %rax」には「63391a7251b1536」が入ります。

 「retq 0x400110」により「cmp %rax,(%rsi)」が命令されます。これは「63391a67251b1536」と%rsiの値、つまり標準入力から受け付けたデータを$0x55で各byte排他的論理和した値と比較しています。

 「retq 0x400102」により「pop %rax」には0x3cが格納されます。

 「retq 0x400129」により「jne 0x40012c」が命令されます。この時のjneは直前の演算結果、つまり「cmp %rax,(%rsi)」の結果で飛ぶか飛ばないかを判断します。この時点ではまだ結果がわからないので2パターンの結果を見ていきます。

 まずは飛ぶ場合です。「cmp %rax,(%rsi)」の結果が等しくなかったらjne命令により飛びます。

 0x40012cに飛ぶと「pop %r10」により0x400119が格納されます。

 「retq 0x400106」により「pop %rdi」には1が格納されます。

 「retq 0x400119」により「syscall」が命令されます。この時のシステムコール番号である%raxは$0x3c、10進数に直すと60になりシステムコールテーブルより「exit」が命令されます。第1引数である%rdiの値が1なのでjne命令で飛ぶ場合は「exit(1)」、エラー終了となることがわかりました。

 次は飛ばない場合です。「cmp %rax,(%rsi)」の結果が等し買ったらjne命令がされず飛ばなくなります。

 「retq 0x400119」により「syscall」が呼ばれ飛ばない場合と同様に「exit」が命令されます。第1引数である%rdiは0なので「exit(0)」、正しく終了することが分かりました。

 解析によりこのプログラムは標準入力から8byteデータを受け付け、そのデータを各byteごとにxorし、その結果をスタックにあった値と比較するものと分かりました。

 標準入力から受け付けたデータを文字列と仮定し、「63391a67251b1536」を「0x5555555555555555」で排他的論理和した結果を文字列に直したところ「c@Np2O16」と言う文字列を得ることができました。ただしIntel x86-64のCPUはリトルエンディアンなので「63391a67251b1536」は「36151b25671a3963」にしました。

 このプログラムは簡易的な暗号の構造ではないかと解析を進めていくにつれ思いました。例えば、パスワードを得るためこのプログラムを「string」コマンドのようなもので確認されても暗号処理がされているので一見分かりません。調べてみるとこれはバーナム暗号に近いものなのではないかと思いました。バーナム暗号は十分に長い乱数を鍵として、平文と鍵をXORすることで暗号文を生成する暗号方式です。今回の場合だと、乱数ではなく「0x5555555555555555」といった予め設定されているものと標準入力から受け付けた文字をXORし、元々ある正しい暗号文と比較するといったものです。バーナム暗号と言い切ることはできませんが、非常に近いものを感じました。これがXORだけでなくANDやORを何回も取り、様々なアドレスへ飛んで暗号生成をするような方法だったら解析がより難しかったと思いました。また、このobjdumpの結果を解析したことで低いレイヤから暗号の生成方法に触れられて面白かったです。他の暗号の生成方法も objdumpの結果から読み取ってみたいと思いました。

 今回初めてobjdumpの結果を解析しました。今までアセンブリ言語に触れたことが全くなく0からのスタートでした。最初は全く訳も分からず右往左往してしまいましたが先生や先輩にアセンブリ言語について教えてもらい、本などを使っていくにつれどんどん分かるようになりました。分かるようになるとobjdumpの解析がとても面白くパズルゲームをやっているような感覚で高いモチベーションを維持し続けながら最後まで解くことができました。最後まで解き「c@Np2O16」の文字が得ることができ、暗号処理をするプログラムだと分かったときはとても達成感を得ることができました。

 この問題を解いたおかげで逆アセンブリコードに大変興味が湧き、これからはどんどん色々なプログラムを逆アセンブルし解析したいと思っています。逆アセンブルの解析がとても楽しかったのでセキュリティキャンプではマルウェアを解析する講座や、逆アセンブルコードを扱うような講座を受講します。様々な逆アセンブリコードを読み解き、アセンブリの世界をもっと深く学び様々な知識を身につけたいです。

選択問題9:マイナンバーカードの配布システムを構築・運用することになりました。あなたなら何に気をつけてどんなサービスを構築しますか?

マイナンバーカードの仕様は現実通りのICカードとします。※ 注意: マイナンバーでは無くマイナンバーカードです。

 私は配布システムを構築・運営をすることになったら個人情報の安全に気をつけ利用者が使いやすいサービスを提供したいです。しかし、利用者が使いやすくすることと、安全なサービスを提供することを兼ね合わせるのはとても難しいと考えます。

 まずは利用しやすい、と言った観点からです。マイナンバーカードを申請、配布までの手続きをできるだけ簡単化したいと思います。具体的にはマイナンバーカード配布までの時間をなるべく短縮したいと考えます。現状のシステムにおいての配布までの流れは、個人番号カードに情報を記入しそれを郵便で各市町村へ届ける。市町村がマイナンバーカードの配布準備が整い次第ハガキを出しそこに記載されている交付場所で受け取る、と言った形式になっています。

 しかしこれでは時間がかかってしまうので私が運用を行うならば次のようにします。行政はあらかじめ何も情報が記載されていないカードを各市町村へ配布しておきます。そしてマイナンバーカードの希望者が出た場合には窓口で受付します。そこで情報をマイナンバーカードに記録し、その場でカードを渡す。その情報を後から行政に市役所が届けるといった形にし、カード配布までの時間を短縮したいと思います。イメージとしては銀行のカードがすぐに作れ、すぐに使えるシステムといった感じです。

 また、現状のシステムでは各市町村は混雑を考えハガキを送る時期を調整すると書いてあります。しかし、私は混雑が予想できるのはマイナンバーが必要となる機会が多い4月の年度始めなどの区切りの時期だけだと考えます。その他の時期で、多くの人はあまり必要としていません。実際、自分の周りではマイナンバーカードを受け取ろうとしている人は聞いたことがありません。なので年度初めはマイナンバーカード配布の時期は窓口を増設して大人数でも対応できるようにし、それ以外の時期でも必要な人が素早く受け取れるようにしたいです。

 次に安全なサービスといった点です。現在のマイナンバーカードの申請方法は「郵便」「パソコン」「スマートフォン」「街中の証明写真機」といった方法があります。自分がシステムを構築・運用するとしたら「街中の証明写真機」は危険なので無くしたいと考えています。「街中にある証明写真」は駅やコンビニの近くなど至るところにあり非常に便利だと思います。しかし、この利便性の高さが裏目に出ていると考えました。

 理由としては「街中にある」といった点と「自分が管理していなネットワークである」といった点の2点です。

 まず1つ目の「街中にある」といった点からです。街中にある、つまり誰からでも見られてしまう可能性が非常に高くなります。「郵便」「パソコン」「スマートフォン」で申請する多くの場合は家の中、もしくはオフィスでになるでしょう。家の中やオフィスならばある程度信頼の高い人が多くいると思います。しかし、街中においては誰がいつ見ているかも分かりません。証明写真機に盗撮機などが仕掛けられており悪意のある第3者に盗み見られてしまう可能性もあります。

 次は2つ目の「自分が管理していないネットワークである」といった点です。証明写真機から申請が行えるのですから当然ネットワークに繋がっています。自分が管理するパソコン、スマートフォンならまだしも誰がいつ使ったかも分からない証明写真機を使うのはセキュリティ上多くの不安が残ります。高いレイヤで通信が盗み見られていたらまだ監視システムが気づくかもしれませんが低いレイヤで通信が盗聴されていた場合には発見するのが難しいと思います。情報に詳しくない人が悪意のある第3者が存在していることに気付くはずもなく、盗聴されているのに気付かないままマイナンバーカードを申請したら個人情報の流出に繋がってしまいます。

 以上の2つの理由より自分は安全を考え「街中の証明写真機」からの申請は取りやめて運用したいと考えています。

 現在、証明写真機同様パソコンやスマートフォンもネットワークを利用しています。ですのでパソコンやスマートフォンが必ず安全とは限りません。しかし、パソコンやスマートフォンは普及が進み1人1台以上持っているのが当たり前になってきました。従って多くの需要が存在するであろうパソコン・スマートフォンからの申請は避けては通れないものと思います。しかしパソコンとスマートフォンでは手軽に申請できてしまう、というところに課題が残ると思います。ですので申請を行う際に、周りの人に画面を覗かれていないか、変な機器が接続されていないか、パスワードは安全なものを使用しているか、などの注意事項を表示させるようにして利用者の危機管理を促し安全に気を配ります。

 マイナンバーカード配布システムをいざ運用しようとなると確実にネットワークを利用します。マイナンバーは個人情報を多く持っているのでこれらの情報が漏洩してしまったら大きな問題に繋がってしまいます。従って構築するにあたりマイナンバーカードに含まれている情報はなるべく閉じたネットワークに置いて管理・運用したいと考えています。またOS・ハードウェア、ネットワーク、アプリケーション、といった各レベルに厳重なセキュリティ対策を施しセキュリティホールをなるべく無くしたいと考えています。ファイヤーウォールやサンドボックスの設置、ウィルス検知ソフトのなども導入し、セキュアなシステムを構築します。

 しかし論理的なセキュリティだけを気をつけるのではなく、物理的なセキュリティにも気を配らなくてはなりません。サーバ室への入室には制限をかけ入退出の管理をします。それに加え、日常的に職員に対してセキュリティのセミナーなどを開き、危機管理能力を高め万が一に備えるようにさせます。そして、万が一個人情報が流出してしまったときのことを考え対応チームを作りどのような対処をするか予め方法をまとめておき問題が起こった時に迅速に行動し対応できるようにします。

 以上のようなことに気を配りマイナンバーカード配布システムの構築・運用を行なっていきたいです。


 以上が選択問題の解答です。添削が残っているやつまたありましたね(笑)

 問題を解くこと自体はとても楽しかったです。特に選択問題8。

 自分は全部の問題に対し感想とまではいかないですが、これを踏まえた上で何が分かって何が分からなかった。だからセキュリティ・キャンプではこんなことを学びたい、みたいなことを書きました。他のプロの方々と比べると知識量が足りず正解をかけていないかもしれませんが熱意やどういったことを学びたいか、などでカバーしたつもりです。

 自分の応募用紙はこんな感じです。知識、技術、経験が足りてないことは重々承知しているのでセキュリティ・キャンプで、はたまたそれ以前それ以降で多くのことを学ぶつもりです。

 来年受ける人の役に立てれば嬉しいです。

 今からセキュリティ・キャンプとても楽しみです!Twitterとか絡んでね。そりでは〜〜^ ^/

PS.

 選択問題1解いた人の答え見てるとすごいですね。全く分かりませんでした。是非教えてください。

 物申したいことがございましたらTwitterの方へ

 

セキュリティ・キャンプ全国大会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難しいですね・・・。罫線の後に文字書くとその前の文字太くなっちゃうんだけどどうしたらいいんだろう。