2017/12/13 Shibuya.XSS techtalk#10 #shibuyaxss 『XSS1000本ノックを支える技術』 See Other => https://knock.xss.moe/
XSS1000本ノックを 支える技術4IJCVZB944UFDIUBML1SFTFOUFECZ!ZBHJIBTIPP
View Slide
whoami➤ 八木橋 優 Yagihashi Yu HN: やぎはしゅ Twitter: @yagihashoo Web: https://xss.moe/ Job: 脆弱性診断 その他いろいろ➤ katagaitai勉強会、 SECCON/SECCON Beginners、 その他・・・2
knock.xss.moe3
今日のメニュー1. XSS1000本ノック #とは2. XSS問題の変遷3. こんな構成4. 課題1「セパレーション」5. 課題2「別解」6. まとめ4
XSS1000本ノック #とは5
katagaitai勉強会➤ 某社のCTFチームが年に2回くらい開催している勉強会➤ 本来はその辺のCTFの過去問を紹介・解説する➤ 2017年春ごろのやぎはしゅ 「夏の勉強会、喋ることになったけど、 資料作るの面倒くさいわ〜…」 「何なら喋るのも面倒くさいわ〜…」 「そうだ、資料も作らず、喋るのも やめればいいんだ!!」 ⇒参加者がひたすらXSSするだけの 最高の勉強会の開催を決意6% 6 (
参加者がひたすらXSSする勉強会➤ 先に決めたこと 1. 資料作らない 2. 解説しない 3. 嫌になるほど長時間やる➤ XSS Challengeを紹介してひたすら解いてもらう? ⇒タダ乗り感がやばくてさすがに罪悪感がやばい ⇒しかも過去問紹介と大差ないので解説圧力がやばい➤ XSS問しか出ないCTFをやればいいのでは? ⇒参加者にWrite-upを書いてもらえば万事解決 ⇒どうせなら1000問くらい出したい ⇒PhantomJS使ったXSS問とか、作ったことはあるけど たくさん作るの面倒くさい ⇒XSS問出題プラットフォームをついでに作ることを決意7
★機密情報を抜くところまでがXSSです ⇒すべての問題でFLAGを盗むのがゴール★ステージ制の導入で圧倒的成長 ⇒現在のステージを解かないと次のステージには進めない★1000問用意しとけばとりあえず最大手になれるのでは ⇒楽に、大量に、XSS問を出題するためのプラットフォーム作りXSS1000本ノック➤ ただひたすらにXSSをキメるだけのCTF➤ 決めたこと 1. alertするだけのヤワなやつは要らない 2. 嫌になるほどXSSばかりやって逆に好きになってもらう 3. XSS Challengeの最大手を目指す8
XSS問題の変遷9
XSS問題の変遷(≒歴史)1. 『正規表現』時代2. 『alert関数置き換え』時代3. 『alert出せたら挙手』時代4. 『箱庭XSS』時代5. 『PhantomJS/Selenium Web Driver』時代6. 『Headless Chrome/Firefox』時代10➤ 僕が見たことのあるCTF等におけるXSS問題の出題手法を 紹介しつつ歴史を振り返ってみる (※私見かつ前後関係は適当)
『正規表現』時代➤ (Web上でいい例がないか探してみたけどなかったよ…)➤ 何のひねりもなく、正規表現でXSSペイロードが正解っぽいかを判定する方法➤ 想定解が正規表現に落とし込めるほど限られているので あれば使えなくもない➤ やぎはしゅも昔々作ったことがあるが大量の想定外の解との終わりなき闘いになるので実際のところ現実的ではない➤ input.match(/alert\(1\)<\/script>/) <br/>⇒img.onerrorでもできるよ!スペースは???などなど<br/>11<br/>
『alert関数置き換え』時代➤ XSS Challenges(https://xss-quiz.int21h.jp/)や XSS Games(https://xss-game.appspot.com/)など➤ 元々のalert関数を自作のものに置き換えて正しい文字列を 引数として渡しているかなどをもとに判定する➤ 実装が手軽にできるので、競技として行うものでなければ これが最適解かもしれない➤ ただし、CTFなど、競技性のあるXSS Challengeの場合は 開発者ツールなどで容易に不正が可能なので不向き 12
『alert出せたら挙手』時代➤ 昔セキュリティキャンプのCTFで見た稀有な例➤ オフラインで開催しているCTFだからこそできる、 alertを出せたら運営を呼んで確認してもらい、FLAGを 教えてもらうという方法➤ お世辞にもスマートとはいえない➤ 趣旨が異なるものの、Cure53のXSS Challengeなど、 最終的に人の目でペイロードを確認するケースも同様かも (賞金あったりするし、これはむしろ妥当)13
『箱庭XSS』時代➤ SECCONの代名詞➤ google:箱庭XSS / google:XSS Bonsai➤ .NET FrameworkのWebControlを使ってIE7っぽい動きをする exeを配布するという狂った斬新な切り口を提示した問題作➤ 僕は好きですよ!次回作待ってます!➤ 実態としては確かalert関数の置き換えをしていたような 気がするので、あくまで発展系(要出典) ⇒ブラウザの開発者ツールやローカルプロキシなどで 悪さができないという点で優秀14
『PhantomJS/Selenium WebDriver』時代➤ いろいろなCTFで多数の事例あり? (ただしPhantomJSは終わった感あるので今後は出なそう)➤ 実際のブラウザ自体を操作、またはエミュレーションする➤ alertを実行できたらFLAG…などの単純な設問から脱却し 管理者ユーザでログイン済のセッションをハイジャックする といった発展的、実践的な設問が可能となった➤ XSS問の多様性の観点ではひとまずここで頭打ち? 実際のブラウザが動くならもうこれ以上はないよね、 という感じ15
『Headless Chrome/Firefox』時代➤ Google CTFなどで実績あり➤ 正直XSS問のためだけにSelenium準備するの面倒くさい➤ PhantomJSのビルド面倒くさすぎ➤ 現れた救世主、ChromeとFirefoxのHeadlessモード!➤ 特にChromeではSeleniumを噛ませずに自在に操作できる➤ FirefoxはMDN見る限りはやっぱりSelenium使ってる➤ 手軽さ、実際のブラウザが動く点でもはや一強といっても 過言ではない16
こんな構成17
構成(ざっくり)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)18a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント
構成(ざっくり)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)19a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント問題毎にVirtualHost分けるphp-resqueで ジョブキュー管理思考停止して Slim + SQLite…
構成(動きのイメージ)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)20a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント①スコアサーバに登録し、 問題ページ(XSSのあるページ)に アクセスする
構成(動きのイメージ)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)21a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント②問題ページ上のXSSで FLAGを窃取するためのペイロードを組む
構成(動きのイメージ)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)22a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント③スコアサーバにXSSが発火する URLを送信する
構成(動きのイメージ)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)23a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント④送られたURLはジョブキューに 登録され、HeadlessChromeが 順にアクセスしていく
構成(動きのイメージ)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)24a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント⑤XSSが発火し、 例えばCookieに含まれているFLAGを 外部に送信するなど被害者ブラウザと 同じ動きをする
構成(動きのイメージ)➤ Nginx+PHP(Slim, php-resque)+SQLite+Node(Puppeteer)25a4ec56…f84.knock.xss.moe89bdae…c4d.knock.xss.moeb53cf3…489.knock.xss.moe問題ページスコアサーバ被害者クライアント⑥得られたFLAGをスコアサーバに 送信し、次の問題に進む
構成(ポイント)➤ 各問題を、可能な限り想定解で解いてもらう(後述)➤ 設問の柔軟性を損なわないため、各問題ページ全てに VirtualHostを切っている ≒proxy_passすればPHP以外で動いている問題ページも 容易に使うことができる (PHPだけでよければサブドメインの値でincludeする内容を 変える方が簡単そう)➤ Headless Chromeを並列でバシバシ実行するのが難しそう (※調べ方が悪いだけ説あり)なので、ジョブキューを 用意してユーザからのリクエストに応じて順次実行する26
課題1「セパレーション」27
同一ホスト上でXSS問を提供することの難しさ➤ 同一ホスト上で大量のXSS問を用意する場合、オリジンまで 同一のものとしてしまうと簡単な問題のXSSを使って別の 問題のFLAGを取得することができてしまうケースがある➤ 素直にSame Origin Policyに頼りたいが問題毎にドメインを 用意するのは面倒くさい(2,3問ならそれもあり)➤ DNSでワイルドカードあてるにしても1000個の問題を サブドメイン毎に効率よく振り分ける方法は考える必要あり28 取りうる選択肢1. サブドメインの値に紐づく問題ファイルをincludeする2. サブドメイン毎にDocRoot分けてVirtualHost切る
1. サブドメインの値に基いてinclude先変える29 ⭕メリット1. *.knock.xss.moeは問題ページを、knock.xss.moeをスコアサーバを、といった具合に、単一のアプリケーションですべて完結する設計が可能2. サブドメインの値に応じてinclude先のPHPファイルを変えるだけなので Webサーバへの負荷は少なそう ❌デメリット1. そもそも単一のアプリケーションで完結するのって便利なのか? (XSS問題の提供プラットフォームとしては逆に不便では)2. PHP以外の言語で作った問題ページを用意するのが大変 (今後特定の言語やフレームワーク依存の問題も出すかも?)
2. サブドメイン毎にDocRoot分けてVirtualHost切る30 ⭕メリット1. proxy_passすれば何でもあり⇒設問の柔軟性を損なわない2. スコアサーバから問題を切り離すことで、スコアサーバの 汎用性向上、問題の管理も楽ちん(別リポジトリで管理) ❌デメリット1. 設定ファイル地獄2. Webサーバへの負荷がちょっとヤバそう (VirtualHost多すぎてNginxの起動時に怒られるw)
2. サブドメイン毎にDocRoot分けてVirtualHost切る31 ❌デメリット1. 設定ファイル地獄 ⇒問題の追加時に設定ファイルも自動で書き換えてしまおう ⇒さすがに気持ち悪いので妥協案を採用(あとで見せます)2. Webサーバへの負荷がちょっとヤバそう (VirtualHost多すぎてNginxの起動時に怒られるw) ⇒設定ファイルへの追記か何かで解決した(はず) ⇒負荷自体は実はそんなでもない?あまりよくわかってなry
結論32倱嶷獌512؋⊠┊猳
課題2「別解」33
別解は1000本ノックにも襲いかかる➤ katagaitai勉強会当日は、たくさんの別解が観測できました➤ 実のところ、あんまり気にしていない ⇒別解も解だよね、というお気持ち➤ せっかくなのでこちらが想定している解法でやってみて 欲しい! ⇒可能な限り想定解以外を削ぎ落とす対策を考える34 よく見かける別解1. 外部ファイル参照(文字数制限がなかったことに…)2. eval+location.hash(文字種の制限もなかったことに…)
Content Security PolicyでXSS対策!➤ 「外部ファイル読み込まれるのツラい…」 「eval実行されるのツラい…」 って、どこかで聞いたことのある話➤ Content Security Policyを使えば外部リソース読み込みや evalの実行を防止することができる!!➤ 本来はまっとうなセキュリティ施策として使われるべき CSPだが、XSS問の別解防止にも大変役に立つので知見として どんどん広めていきたい➤ 実際の例を見るのは1000本ノックを受けてもらえばいいので ここでは1つだけ具体例を紹介する 35
Content Security PolicyでXSS対策!(具体例)36header('X-XSS-Protection: 0');function myescape($s){return substr($s, 0, 65);}?>= myescape($_GET['q']) ?>CSP導入前header('X-XSS-Protection: 0');header('Content-Security-Policy: script-src \'self\' \'unsafe-inline\' \'unsafe-eval\'');function myescape($s){return substr($s, 0, 65);}?>= myescape($_GET['q']) ?>CSP導入後65文字以内でCookieを 抜き取る問題だが「//gj.gy」などで 外部ファイルを参照すると だいぶハードルが下がるCSPで外部オリジンの スクリプトの参照を 禁止することで、 想定外の解法を潰しこむ
結論37倱嶷獌%52؋㧡涹猳
デモ38
まとめ39
➤ 資料作らない ⇒使い回しの自己紹介スライドとURL掲載用のスライド以外 使わなかった!➤ 解説しない ⇒前に立たない代わりに個別に回って詰まってる人向けに 解説・アドバイス ⇒結果的に各参加者の習熟度に合わせた話ができた➤ 嫌になるほど長時間やる ⇒4時間ぶっ通しで参加者がXSSキメ続ける異様な空間を 具現化した当初の目標と達成度合い40
knock.xss.moe41
Any Questions? Feel free to ask me onTwitter(@yagihashoo)!42