2016年5月25日水曜日

Amazon.co.jpの新機能にあったXSS

先日久しぶりにAmazon.co.jpにアクセスしてみると、何やら見慣れないボタンが右上に追加されていました。

    

どうやらAmazon.co.jpを利用するときの言語を設定できる機能のようです。

   

この機能のURLは以下のような形になっていました。
http://www.amazon.co.jp/gp/customer-preferences/select-language/ref=topnav_lang?ie=UTF8&preferencesReturnUrl=%2f

怪しい気配がしますね。
試しに、「'」(%27)をURLの末尾に挿入して出力されるコードを確認してみます。
http://www.amazon.co.jp/gp/customer-preferences/select-language/ref=topnav_lang?ie=UTF8&preferencesReturnUrl=%2f%27


あっ…(察し)
先ほど入力した「'」がエスケープされずに出力されてしまいました。
どうやらこの箇所はユーザから入力された値を適切にエスケープできていないようです。
これでalertが出せそうということが分かったので、JavaScriptの構文のエラーが出ないようなコードを書いて追加で挿入します。
http://www.amazon.co.jp/gp/customer-preferences/select-language/ref=topnav_lang?ie=UTF8&preferencesReturnUrl=%2f%27%3B%7D)%3B%7D)%3Balert(1)%3B(function()%7B(function()%7B%27

alertが無事画面に表示されました!

この問題は発見した当日にAmazonに報告をして、本日修正を完了したとの連絡をいただいています。
最後に、修正が完了したあとの同機能のスクリーンショットを貼っておきます。


( ˘⊖˘).。oO (存在自体が消されてしまった…)


2016/05/26 追記
本日確認したところ、同機能が復活していました。

2016年4月28日木曜日

[CVE-2015-7214] data および view-source URI を通じたクロスサイト読み取り攻撃 (write-up)

詳細

MFSA 2015-149: data および view-source URI を通じたクロスサイト読み取り攻撃

PoC (Mozillaに公開の許可を確認済み)

https://github.com/llamakko/CVE-2015-7214

  • www/index.html
    • Web上のSOP(Same-Origin Policy)バイパスのPoC
  • local/index.html
    • ローカル上のSOPバイパスのPoC

解説

この脆弱性を発見するきっかけとなった挙動から順に解説していきます。

なお、この解説は www/index.html にあるPoCの内容が基点となっています。


Firefox 42.0のe10s環境では、http(https)なURL上で location.protocol を用いてスキームを data に変更するとアドレスバーの表示は変わらずにブランクページに遷移する挙動が存在しました。

この挙動では、スキームを変更後も変更前のオリジンからDOMの操作が可能でした。

僕はこの挙動をアドレスバー偽装のトリガーに使えるかもしれないと考え、開発者ツールで検証を行ってみたところ、以下のような挙動を発見しました。

  1. https://example.com にアクセス
  2. location.protocol="data"
  3. location.host="www.google.co.jp"
  4. location.protocol="https"
  5. history.back()

上記の操作を開発者ツール上で行うと、アドレスバーの表示は https://www.google.co.jp で、ページにはオリジンが https://example.com のブランクページが表示されている状態となります。

これはアドレスバー偽装が成功しているように思えますが、このままではWebページ上のみの操作で再現することができず、もしそれが可能になる方法を発見したとしてもブランクページが表示されるわけなのでユーザに対して攻撃することができない、と考え、まずは location.protocol="data" を行ったあとのページに偽装したいページと同様の表示をさせる方法を探すことにしました。

この挙動の再現方法は嬉しいことに data URL Scheme を用いているため、 data:text/html,[任意のHTML] という形にできればページの偽装も成功させることが可能と考えました。

そこで、まずは以下の方法を試してみます。

location.protocol="data"
location.host="text/html,"

上記の方法では location.host の中に /, が含まれているため、期待している形通りにURLを変更することができませんでした。

他に良い方法がないか考えてみたところ、以下の方法を使えば location.host に上記のような記号を含めずに先ほどの形の表現が可能だと考えました。

location.protocol="data"
location.host="text"
location.pathname="html,foo"

しかし上記の方法ではダウンロード用のダイアログが表示されてしまい、ページはブランクページの状態から変更ができませんでした。

その後 location.host の制約が面倒だと感じたため制約の抜け道を探してみたところ、 blob URI Scheme 内で location.protocol="data" を行ったときは location.host などのLocationオブジェクトのプロパティが参照する箇所が以下のようになることを発見しました。

blob:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe
↓ location.protocol="data"
data:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe

<location.protocol>:<location.pathname>

このとき、 data の箇所を location.protocolhttp://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe の箇所を location.pathnameでそれぞれ変更することができます。

なお、この場合では location.host の変更はできなくなりますが、今までは location.host で変更していた箇所を location.host と比べて制約が非常に少ない location.pathname で変更することが可能になったため、問題であった location.host の制約からは抜けられることになります。

このあたりからこれらの挙動はアドレスバー偽装より重要度の高い脆弱性のトリガーになり得るのではないかと思い、別の目線で検証をしてみることにしました。

その中で見つけた挙動が以下の挙動です。

blob:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe
↓ location.protocol="data"
data:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe
↓ location.protocol="view-source"
操作しているタブがクラッシュ(e10s環境ではない場合はFirefox自体がクラッシュ)

普段ならバグハントでクラッシュが起きることは嬉しい現象なのですが、今回のケースでは更なる検証を阻害する邪魔な要素でしかありません。

そのためなんとかしてクラッシュを回避できないか試してみたところ、以下のように view-sourceview-source を参照することでクラッシュの回避が可能なことを発見しました。

blob:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe
↓ location.protocol="data"
data:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe
↓ location.pathname="view-source:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe"
data:view-source:http://example.com/ff11ec98-c4ce-4ace-b66d-e6ccaf69bdfe
↓ location.protocol="view-source"
クラッシュはせずにview-sourceの内容が表示される

さらに、この手法と window.open を用いて子ウィンドウに対して親ウィンドウのドメインとは全く関係のないドメインのview-sourceを参照させようとしたケースでも、正常にそのドメインのview-sourceの内容が表示されることを確認できました。

ここで試しに全く関係のないドメインのview-sourceを参照している子ウィンドウのDOMに対して親ウィンドウからアクセスを試みたところ、なんとアクセスが成功してしまい、結果、今までの挙動をSOPバイパスの脆弱性へと結びつけることに成功しました。

後日談ですが、アドレスバー偽装に使えそうな挙動に関しては最終的にページを偽装する方法を見つけることができなかったのですが、のちに偽装させる方法を発見することができ、今回の脆弱性の修正後に別途Mozillaに報告をして脆弱性として認定されました。

以下は、その脆弱性が修正されたときに公開された情報です。

MFSA 2016-28: 履歴遷移と Location プロトコルプロパティを通じたロケーションバー偽装

また、この脆弱性の修正後に別の手法を用いることで同じような挙動を再現できることに気づき、あとはDOMへのアクセスを成功させるだけで同様の脆弱性へと結びつけられる、という段階までいっていたのですが、モチベが続かずにしばらく放置していたところ、いつの間にかその手法に使っていた挙動が防がれていました…。

2016年1月12日火曜日

Firefoxのバグを見つけて5000ドルの報奨金をもらった話

先日、僕が報告したFirefoxというブラウザのバグが修正され、開発元のMozillaのサイトにそのバグの概要が掲載されました。


開発元のMozillaは、Bug Bounty Programという自分たちが開発した製品、サービスのセキュリティ上のバグを発見してくれた人に対して報奨金を支払う制度を設けています。
このBug Bounty Programという制度は、Mozilla以外にもGoogle、Microsoft、Facebookなど様々な企業、団体が取り組んでおり、最近では日本の企業もこの制度を取り入れるところが徐々にですが増えてきています。

通常、Bug Bounty Programで支払われる報奨金の額はバグの重要度で決まります。
Mozillaの場合はその重要度が4段階に分かれており、重要度が低い順から以下のような分類になっています。

低(Low)→中(Moderate)→高(High)→最高(Critical)

その中で、今回僕が報告したバグはMozillaから最高(Critical)に相当する、という評価を受けまして、報奨金として5000ドルをいただくことができました。
このときに見つけたバグの詳細については、近いうちに某勉強会にて発表させていただこうと思っています!

2014年の7月頃から始めた情報セキュリティで、憧れのバグハンターの方を目指して今までやってきましたが、この件でようやく見習いバグハンターとして一皮むけることができたような気がします。
今年はより一層憧れのバグハンターの方に近づけるように精進したいです(,,Ծ‸Ծ,,)