げんたろう's備忘録

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

C1 ブラウザの脆弱性とそのインパクト

スライド資料については
https://speakerdeck.com/nishimunea/burauzafalsecui-ruo-xing-tosofalseinpakuto
にてアップロードされています。
記述することのほとんど全てはスライド上にあります。
また、内容については僕がスライドを読んで思ったこと、考えたことを書いています。なので、お二人の思いや伝えたい内容を十全に伝えられていない可能性もあります。
真にお二人の話された内容を知りたい方は上記の資料を読まれることをおすすめします。

講師のお二人の簡単なプロフィール

Masato Kinugawaさん
ドイツのCure53という企業に所属されている。
ご飯を食っていけるぐらい脆弱性報奨金で稼いでた(現在進行形かもしれない)

西村 宗晃さん
株式会社リクルートテクノロジーズに所属されている。
朝電車でコミット履歴とか仕様書とかを読んで日夜脆弱性を探しているらしい・・・。

講義

講義は、お二人の経験に基づく脆弱性探しのポイントをお話しされる形です。

ブラウザのモジュール

ブラウザがいろんな機能を持っていることは、多くの人が知っている事実ですが、それらは多くのモジュールによって構成されています。
まずはブラウザはどのようなモジュールで構成されているかを知るところから始まりました。

ブラウザには、Html,XML,SVG...等々のパーサやJS,VBS,asm.js等々のスクリプトエンジン、ネットワークプロトコルなどなどなどなど・・・・
物凄く沢山あるらしいです。
そりゃあ脆弱性の1つや2つや100つぐらいありますよね。

プロが教える脆弱性発見の狙い目

  • 新しい機能

そうか!新しい機能か!確かに新しい機能は洗練されてない!

  • 古い機能

確かに!古い機能はセキュリティ意識なく記述されたものもあるのかもしれない!

あれ?全部じゃない?

とかいう冗談は置いておいて、
新しい機能については、やはり洗練されていない可能性があります。
また、古い機能についても長い間注目されて調査され尽くしている機能ならばいいですが、結局マイナーな機能として使われることが少なかった機能や標準化されていなくて仕様が不明確なものなどには脆弱性発見のチャンスがあるらしいです。

  • 概念のまとまりを列挙してその中から探す

例えば、HTTPリクエストを送信できるAPIだとか、windowオブジェクトにぶら下がってるものだとかそういう列挙されているものの中から探す。

  • コミット履歴から探す

これがめっちゃ面白そうでした。新しいモノならワンチャンあるんじゃないか、そう思えました!

  • 攻撃のシナリオをイメージする

攻撃のシナリオをイメージして、ブラウザが本当にその攻撃シナリオを防げる仕様になっているかを見ていく。
例:
CSPが正しく機能しなければ...という攻撃シナリオを考えたなら
→CSPの実装が正確かを見てみる

  • 過去に学ぶ

過去に修正された脆弱性情報を見る。大体人間がやる間違いは似たようなものなことが多いのは何となくこれまでの人生経験からも感じられますよね。

実際にコミット履歴を見て、脆弱性を見つけてみる演習

演習としては、以下の修正が題材として挙げられ、その中の脆弱性を見つけるお題でした。

https://github.com/mozilla-mobile/firefox-ios/commit/78be54586c9e027465d8e0da28bb42595d4ebe32
https://github.com/mozilla-mobile/firefox-ios/pull/2249/files

是非皆さんも探してみてください。
(解答等は冒頭に上げた資料の38スライド目あたりにあります。)

でも実際に数あるコミットの中から脆弱性があるものを見つけ出すのって、相当根気とかいろいろ必要ですよね。

KinugawaさんがKinugawaさんに成れた要因

  1. はせがわようすけさんの資料を熟読(http://utf-8.jp/)
  2. XSSの手法の勉強
  3. 手を動かして実際に再現
  4. さらに深堀り

https://l0.cm/encodings/table/
全ての文字コードの動作を一から調べられたとのこと・・・。
すげえ・・・文字コード一体めっちゃあるやん・・・
思ったよりも5倍ぐらい沢山ありました。
後は、about: URLをひたすら解析とかサードパーティライブラリの脆弱性探しなどもやられたそう。

素人が脆弱性を見つけられると思うな!

脆弱性を見つけたい対象のことを深く知っていなければ脆弱性は見つけられない。当然のことですよね。
モジュールの目的・使用用途、入出力、制限事項、そのモジュールを経由することで何かをバイパスできないか等々モジュールについて知る必要があります。

深く知るために
  1. 実際に動かす
  2. 仕様を読む
  3. コードを読む
  4. バイナリを読む

バイナリを読む!!!!!

誰が予想したでしょう、Web脆弱性の講義の中でバイナリを読むことを・・・!

f:id:gntrua:20170822141316p:plain
edge用はC:\Windows\System32\edgehtml.dll
IE11用はC:\Windows\System32\mshtml.dll

例えば、
{<[?]?im{p}ort[ /+\t].*?implementation[ /+\t]*=} を見てみると、importの「p」を別のものに置換するっぽい感じの雰囲気のような何かは感じられます。言われないとわかりませんね。
この部分のバイナリコードはXSSフィルターに関する正規表現が記述されているとのことでした。
(なぜ分かったのか聞き逃した・・・。)

つまり、ここに書かれている正規表現を理解したうえで、何とかバイパスするXSSを考えてみよう、ということです。

そこで、この正規表現を理解するために実際に動かしてみよう、ということで演習がありました。

そもそもXSSフィルターとは?

https://www.slideshare.net/codeblue_jp/xssxss-by-masato-kinugawa
より

「リクエストの値とレスポンスから
危険と判断される条件にマッチすればページを書き換える」

らしいです。

例えばリクエストで送っている内容をそのままWebページに表示していてかつ、その内容がscript実行に繋がる可能性がある場合にページの内容を書き換える
みたいな動作かと思います。

とりあえずXSSされそうだったら、いい感じに書き換えてくれるぐらいの理解しか持てていません。
厳密な条件は中々わからないのかな~

そうした中で

XSSフィルターの反応原因を探る演習

Kinugawaさんが用意された
https://goo.gl/WSEkgq
を使って、どの正規表現が反応してフィルターをかけられてしまっているのかを調査。

今回、

"instagram(インスタグラム)"

"instagram#インスタグラム#"

にフィルタリングされてしまっている。

f:id:gntrua:20170822153923p:plain

上記したバイナリをよーく読むことで

{[\"\'].*?{\)}[ ]*(([^a-z0-9~_:\'\" ])|(in)).+?{\(}.*?{\)}}

の辺りが反応していることが見つけられる。

f:id:gntrua:20170822153643p:plain

実際、上記のようなXSSは実行可能で
Kinugawaさんが用意された
https://goo.gl/Vmkebc
で試せる。

考察

q = "入力"

みたいな部分があったときに

q = "" alert(1)//

を試すんだけど、前半の式とalert()が繋がってしまっているから実行されないという問題の解消のために

q = "" in alert()//

とするんだろうと考えました。

なら例えば

q = "" * alert() //

できるんじゃね?ということですが
上記の場合でも上手くいきます(下記画像)
f:id:gntrua:20170822152201p:plain
しかし、やっぱりこれも当然
f:id:gntrua:20170822152313p:plain
XSSフィルターによってフィルタリングされます。
その中そんなに甘くねえ!

APIの仕様書を読んでルールを明確化してみる演習

仕様書の内容を理解していきます。そうすると、どのパラメタはどういう値が許されているかなどを明確化できます。
そして...

仕様通り動くかを調べるだけで脆弱性が見つかる

世の中甘いかよ・・・(深い知識が必要です)

対象のおかしな動作を探す

おかしな動作はすなわちバグであっても、時には悪用可能かもしれないこともあるとのこと。

おかしな動作 × 何か = 脆弱性
になる・・・可能性もある。

CSPバイパスXSSチャレンジの演習

おかしな動作からヒントを得、CSPをバイパスしてXSSをします。

CSPとは

Content Security Policyのこと。
WebサーバがHTTPヘッダのContent-Security-Policyにポリシーを設定します。
例えば、

Content-Security-Policy: default-src 'self'

とすると、全てのコンテンツを自身のドメインから取得するよう設定できますし、

Content-Security-Policy: default-src 'none'

と設定すれば、いかなるドメインからのコンテンツの読み込みも許可しません。
また、

Content-Security-Policy: script-src 'nonce-hogehogehogehogehoge'

と設定されていると、

<script nonce="hogehogehogehogehoge">alert()</script>

と正しいnonceが設定されているscriptタグのスクリプトのみが実行されます。

演習

https://vulnerabledoma.in/camp2017/csp

上記もURLパラメタに入力した文字が表示されるようになっています。
これを使ってCSPバイパスXSSにチャレンジします。

解答については、冒頭のスライドの85スライド目にありますので、参照してください。

仕様変更につながることも

こうした脆弱性の発見によって、仕様そのものも変わることもあるそう。

悪用のシナリオを考える

めっちゃ悪そう。
でも、やっぱり実際に示さないと人には理解して貰えない・・・。

演習

https://github.com/nishimunea/securitycamp2017
Firefox拡張には、脆弱性があってそれを最大限悪用するとどれだけのことが出来るのか?という演習でした。

解答については、冒頭のスライドの94スライド目にありますので、参照してください。

結論から言うと、
ページ内の全コンテンツを外部に送信可能
らしいです。
やばい・・・。
西村さんはgmailでデモされていましたが、他人とのメールが外部に送られたら困りますよね・・・。

結局

脆弱性探しは十人十色
らしい。結局!!!
まあ、そりゃそうですよね。
~プロが教える脆弱性探しの完全攻略~
とかいう本があったら誰も脆弱性生まないですよね。