seccamp2015応募用紙内容#1

久しぶりのブログですね。

seccamp2015無事合格することができたので、応募用紙を晒そうと思います。
共通問題と選択問題3,4,8,10,11といたのですが、共通問題と選択問題3はいいかな…

ってことで共通問題4,8,10,11そのまま貼り付けます。

画像とかいろいろ形式変えなきゃ貼り付けられなくてうーんってとこは(略)にしてます、ごめんなさいw

(文字数が多すぎるため、記事二つになっています。)

---------------------

■選択問題4

(1)

私は今回、www.cfgbj.com121.199.37.219)に興味を持ったので、pingを打つターゲットとしました。

まず、pingについて説明します。

pingは、ICMP”echo request”パケットを対象のノードに投げて、相手から”echo reply”が返って来ることを確かめることでネットワーク回線の状況を知るためのものです。

ネットワーク回線を調査するために送るものですが、回線の状態が正常でネットワークが繋がっている場合であっても、サーバの設定などにより”echo reply”を送らないようにしているところもあるので注意が必要です。

 

pingを5回打った結果を以下に示します。

(略)

ICMPパケットは、大きさは64bytesTTLは128で飛ばしています。

なので、20個の中継機器を通過してターゲットのサイトに到達していることが分かります。

パケットを送信してからreplyが返ってくるまでの平均時間は138.795 msとなりました。

このサイトに興味を持った理由としては、昔私が中国に滞在していた頃、このサイトに載っているマンションに住んでいたからです。

中国では珍しい日本語が通じる従業員を必ず配置しているホテルが隣接し、中国在住の日本人が多く集まっている場所だったこともあり、中国の中で特殊な場所となっています。

また、中国というのはインターネット上のコンテンツ全てが国の検閲下で動いていると言われているため、中国国内のサイトがどのような通信をしているのか関心を持ちました。

 

(2)

低レイヤーのネットワーク通信の仕組みについての考察をします。

まず、このサイトにtracerouteコマンドをかけてみると、以下の結果となりました。

 

traceroute to www.cfgbj.com (121.199.37.219), 64 hops max, 52 byte packets

 1  192.168.2.1 (192.168.2.1)  1.398 ms  1.327 ms  1.013 ms

 2  ----(---.---.---.---)  1.634 ms  1.578 ms  1.641 ms

 3  ----(---.---.---.---)  6.082 ms  5.627 ms  4.793 ms

 4  ----(---.---.---.---)  4.784 ms  5.286 ms  5.375 ms

 5  ----(---.---.---.---)  5.869 ms  5.792 ms  5.535 ms

 6  ----(---.---.---.---)  6.903 ms  5.175 ms  5.379 ms

 7  xe-0-5-0-7.r01.tokyjp01.jp.bb.gin.ntt.net (61.213.161.117)  6.437 ms  5.825 ms  5.489 ms

 8  ae-12.r21.tokyjp05.jp.bb.gin.ntt.net (129.250.5.177)  5.641 ms  5.897 ms  5.713 ms

 9  p64-2.chinanet.tokyjp05.jp.bb.gin.ntt.net (129.250.66.62)  187.350 ms *  189.058 ms

10  202.97.35.105 (202.97.35.105)  191.711 ms  193.056 ms  192.045 ms

11  202.97.33.85 (202.97.33.85)  195.360 ms  197.610 ms  199.588 ms

12  202.97.55.14 (202.97.55.14)  346.863 ms *  1436.815 ms

13  220.191.135.158 (220.191.135.158)  1688.775 ms  259.392 ms  546.521 ms

14  115.238.21.121 (115.238.21.121)  1713.436 ms  929.798 ms  918.840 ms

15  42.120.244.190 (42.120.244.190)  247.175 ms  266.397 ms  2542.085 ms

16  42.120.244.234 (42.120.244.234)  474.716 ms  410.401 ms  239.730 ms

17  * * *

18  121.199.37.219 (121.199.37.219)  185.212 ms  186.452 ms  184.105 ms


tracerouteはランダムなポートのUDPデータグラムを使用し、TTLを1から徐々に増やしていき、目的のノードまでに経由している機器を調査するものです。

念のため、結果の2-6のところは伏せさせていただきました。

伏せたところの通信に関しては、私の家のインターネット回線がNTTと契約している関係で、NTTルータなどを通過しています。

この結果をみてはじめに気になったところは、8,9番目です。

ホスト名が少し気になったので、調べてみたところ、アメリカのIPアドレスでした。そのため、NTTのアメリカにある基地局を経由していると予測できます。

もう少し詳しく調べると、NTTから中国のサーバへと通信する際、129.250.66.62が日本と中国のネットワークを繋いでいるのが分かりました。

そして、ここから中国のネットワークになるのですが、通信の検閲か何かがはいっているのかただ距離的に時間がかかっているのかはわかりませんが、応答時間が1秒越えとかなり遅くなっています。

そして、17番目の中継機器の応答がないことがわかります。

wiresharkを使ってパケットを眺めていたところ、通常TTL0で届くとTilme-to-live exceededを返すのですが、17番目の中継機器が返すはずのパケットがDestination unreachableとなっていました。

次の結果で目的ノードである121.199.37.219に3回とも正常に到達していることから、17番目の機器は、中継用ではなく特定されないようにしている監視用の機器ではないかと予測しました。

tracerouteからわかったターゲットサイトへのネットワーク通信路を以下の図に簡単にまとめます。

 (略)

また、サイトが動いているサーバの状態を知るためにnmapによるポートスキャンを行おうと考えたのですが、ポートスキャンはサイバー攻撃の予備動作と捉えられていてあまりローカル環境以外で行うのは好ましくないと言われています。

ましてや対象のサーバが国でインターネットを監視している中国にあるのを考えると、今回はしないほうがいいと判断したため、ポートスキャンによる調査は控えさせていただきました。

 

では高レイヤーでのネットワーク通信について考察します。

HTTP通信をしているはずであるため、burpを使い、HTTP通信の動きを調査しました。

このサイトのみアクセスしている環境にし、調査したところ、このサイトを1回開くために27回ものHTTP通信をしていることが分かりました。

以下が通信結果を表示したburpの画面となります。

 

(略)


まず、最初にサイトのHTMLが送信されています。

そのあとに、大量のjavascriptが送信されてきています。

おおよそサイズは10KB前後で、大きいものでは100KB近く、小さいものでは258Bのものもあります。

合計だとこのwebページを表示するために受信する合計サイズは約350KBとなっています。

少し気になったところとしては、ところどころにcnzz.comと通信している記録があったことです。

なんの機能なのか少し調べてみたところ、cnzzというのは中国の個人の方が運営しているWEBアクセス解析サービスのことであるようで、中国のほとんどのサイトはcnzzを利用してアクセス数やアクセス先などの通信を解析しています。

そのため、今回のターゲットサイトであるwww.cfgbj.comcnzzを利用していて、アクセスしてきた利用者にリクエストをそちらに飛ばすようにしていると推測しました。

また、ヘッダーを見ると、まずETagを使っていることが分かりました。

ETagというのは、キャッシュを効率化するためのHTTPレスポンスヘッダーの一つで、URLのリソースに変化がないかどうかを判定してキャッシュを有効活用するもので、編集の際に複数人が同時にリソースを書き換えてしまわないためにも活用されています。

送受信の途中、Connectionkeep-aliveになっていて、連続でデータを受信していることがわかります。

また、さまざまなディレクトリに散在しているデータを受信していることがわかります。

さらに、cnzzではX-○○という自作ヘッダーがいくつか使われていて、そのヘッダー情報からアクセスした時間やキャッシュの処理をしていると考えられます。

以上がHTTPでのネットワーク通信における考察です。

 

さらに、wiresharkによりサイトにアクセスした時のパケットをキャプチャしてどのような通信をしているのか考察します。

サイトにアクセスした際の通信の全体的な流れとしては、まずDNSにより、ドメイン名からIPアドレスを調査します。

そのあと、TCPによるスリーウェイハンドシェイクを行っていて、他のサーバに接続するときには通信をfinフラグで終了していました。

途中、cnzzに通信する際は逐一DNSで名前解決していました。

また、全体的に通信時は定期的にkeep-aliveして通信の速度上昇を図っていることがわかりました。

他には、特に通常のHTTP通信と変わりなく、burpによるHTTP通信の解析と同じ結果となりました。

 

(3)

このサイトと私のPC間では、物理的には光ファイバーを用いて通信していて、ネットワーク層ではIPv4トランスポート層ではTCP、そして高レイヤーではHTTPを用いて通信をしていて、javascriptを用いたwebサイトを見ることができるようになっています。

用いられているHTTPの規格は1.1です。

このwebサイトはjavascriptが多くあるため、また単純に海外のサーバのためサイトをブラウザ上で表示するまでにやや時間がかかってしまっています。

そこで、今後実現したほうがよいと思うのは、HTTP/2に対応することです。

HTTP/2は今年の5月にRFCで文書化されたばかりのHTTPの新しいバージョンです。

HTTP/2HTTPを元に高速化を行ったプロトコルであるSPDYを組み込んだもので、従来のHTTP/1.1の機能にかぶせるような形として開発されました。

HTTP/2は1つのTCP接続で仮装のストリームチャンネルを生成して、全2重多重化通信を可能にしています。

そして、HTTP/1.1輻輳制御にくらべ、帯域を最大限まで効率的に使えます。

さらにヘッダーを圧縮することができるようになったため、通信の高速化を測れます。

また、SPDYTLSの上で動くことが必須条件であり、HTTP/2でもセキュリティ面からFirefoxなどはTLSを利用した通信しかサポートしていません。

今後、4K画像や複雑なscriptなどが埋め込まれるサイトが増えると予想されるので、HTTP/2に対応するといいと思います。

ですが、現時点ではHTTP/1.1で十分という声が多く、無駄にややこしくなっているだけと言われていることが多い為、普及するにはもう少し時間がかかりそうです。

このHTTP/2を使うと、サイト側の負荷が増えることが予想できます

そのため、サーバ負荷分散などの技術を共に利用していかなければならないでしょう。


-----------------

選択問題8 

gccには、stack smashing  protectionというセキュリティ機能が備わっています。

このセキュリティ機能は-fstack-protectorというオプションでコンパイルすると有効になるもので、ほとんどの場合デフォルトで有効となっています。

これを無効にするためのオプションとして-fno-stack-protectorが用意されています。

-fno-stack-protectorを用いると、-fstack-protectorの機能が無効になります。

 

stack smashing protection機能は、ソフトウェアをbuffer overflow などスタックの破壊を狙ったstack smashing attackから守るためのものです。

コンパイル時、関数のリターンアドレスとebp退避領域の前に4バイトのカナリアというワードを配置します。

カナリアは、ローカル変数領域の溢れによるスタック破壊を検知するものです。

ローカル変数領域の溢れが起こった際、付加してあるカナリア値が書き換わり、関数からのリターン直前にカナリア値が変わっていないかをチェックし、それによってスタック破壊を検知します。

そして、スタック破壊を検知したら、プログラムの実行を中止する関数に飛び、プログラムを強制的に中止させます。

ただし、ローカル変数の中に文字列が8バイト未満しかないと言われている場合、スタック破壊検出コードは生成されません。

この閾値を変更するには、--param ssp-buffer-size=N(Nは設定したい閾値)オプションをつける必要が有ります。
特に、閾値を無くす、すなわちすべての関数に対してスタック破壊検出コードを生成する場合は –fstack-protector-allをオプションとしてつけるとできます。

また、-fstack-protectorオプションは、配列とポインタ変数などが共存するプログラムがある際、配列をポインタ変数などよりも後のアドレスに配置し、stack smashing attackなどが発生した際に被害をなるべく最小限に止められるようにする機能も付いています。

このほかに、WindowsVisualC++には-fstack-protectorとほぼ同じようなオプション「/GS」があり、こちらもVC++2005からデフォルトで有効となっています。

こちらは、カナリアの代わりにクッキーというもので破壊を検知するのですが、機能としてはほぼカナリアと変わりません。

相違点としては、-fstack-protectorでは、カナリアはプロセスごとに値が変わりひとつのプロセス内は値が共通なのに対し、/GSではプロセスごとに決められた値と関数が呼び出された時点でのbpレジスタが持っている値をXOR演算した結果をクッキーとして設定しています。

-fno-stack-protectorオプションをつける場合とつけない場合の比較をするため、gccを用いて実際に簡単なコードを書いて実験してみました。

ソースコードは以下の通りです。

 (略)

まず、このソースコードgcc-fno-stack-protectorオプションをつけてstack smashing protectionを無効にしてコンパイルしました。

そして、実行ファイルをobjdump –dで逆アセンブルしました。

本来ならば、ディスアセンブル結果を全て掲載して比較するべきであるのですが、GOTテーブルなどあまり関係のない内容が多く非常に長くなってしまいます。

そして、今回はstack smashing protectionカナリア値が壊れているかの確認をしているかがわかれば良いため、以下にmainの結果のみを示します。
(略)

これを見る限り、スタック破壊を起こしたとしてもプログラムを強制的に止めるものがないためスタックが保護されていないと予測できます。

そして、配列から溢れる入力値を入れて実行した結果が以下になります。

(略)

明らかにあふれている値を入れているのに、エラーが起きないため、stackを破壊して関数の戻りアドレスを書き換えることが可能ということがわかりました。

よって、このプログラムは任意のシェルコードを実行することができる、バッファオーバーフロー脆弱性があります。

 

次に、stack smash protection機能をつけた状態でコンパイルしました。

以下に、objdumpによる逆アセンブル結果のうち、main部分を示します。

(略) 

上記のstack smash protectionを無効にした場合と比べて、ところどころ内容が追加されているところがあります。

注目すべき場所としては、0x400686において_stack_chk_failという関数が呼び出されているところです。

これは、stack smashing protectionがスタックの破壊を検出した時に呼ばれる関数で、エラーを出力し実行を停止してくれます。

これにより、このプログラムはstack smashing attackから保護されている安全な状態になっていると言えます。

実際に実行して、スタック破壊を起こす値を入力した結果を示します

(略) 

スタックを破壊しカナリア値が書き換わったのを検知して、実行を中止していることが確認できました。

 

ですが、先ほど確認した__stack_chk_failという関数は、libc.soの中に入っていて、プログラムから呼び出す場合PLTを経由してしまうため、例えばプログラムにformat string attackができる脆弱性があった場合、__stack_chk_failGlobal Offset Table overwriteすることにより任意のシェルコードを実行できてしまう危険性があります。

このように、プログラム中のスタックが保護されているからと言って必ずしも安全なプログラムができているとは限らないことに注意が必要です。




-----------------


文字数の関係で次の記事に続きます。