之前对xss接触比较少,只是会基础的alert操作,至于原理,为什么可以这么编码等问题一直都是模模糊糊的,所以这段时间恶补一下xss基础知识。大佬略过,如果文章内容有什么不对的地方还请大家斧正!
在文章开始之前先放两个链接,都是可以加深对js,html编码理解的文章,个人觉得非常优秀。
《XSS与字符编码的那些事儿》---->http://www.2cto.com/article/201310/251830.html
《深入理解浏览器解析机制和XSS向量编码》------>http://bobao.360.cn/learning/detail/292.html
如果有刚开始接触xss的像我这样的新手,应该会有和我一样的经历,就是对html编码,js编码分不清楚。什么时候该用html编码,什么时候用js编码呢?
本人对这些进行了一个简单的概括:
最常见的html编码有:html实体编码。分为十进制和十六进制
如把尖括号编码[ < ] 十进制: < html十六进制:<(这里的分号是可以省掉的)
最常见的js编码有:八进制,十六进制,jsunicode编码。
如把尖括号编码[ < ] 八进制:74 十六进制:x3c unicode:u003c
js和html不是同一种语言,所以就分为html解码和js解码。html只能识别属于自己的编码,js也是一样。因此html解析起并不能识别十六进制或者八进制的js编码。当然js也不能识别html实体编码。所以一般在domxss中大多是不用html编码的。再说一句,浏览器在解析代码的时候是先html解码,然后url解码,最后再运行js解析。所以这里可能就会有一种情况绕过,就是实体编码和js编码一起合作。上面的这边文章有例子可以看看,《XSS与字符编码的那些事儿》说的已经很清楚了就不赘述了。
剩下的就是url编码和base64解码,这两个大家都很熟悉就不多说了。
接下来就记录一下菜鸡的我做xss challengs的思路和心得!
tip:(因为本人是用比较常见的chrom浏览器去复现,所以关于需要其他浏览器才能实现的情况只做思路说明。)
第一关很简单什么都不用编码直接输入payload就会弹窗
这里提示说要闭合上一个标签。所以也很简单,直接
"><script>alert(document.domain)</script>
这里很明显在box中进行xss。看似只有这几个选项实际上是post传参的,可以bp抓包修改。也可以在element里面改。
这里通过提示可以知道有转义
但是可以看到hiden这p3也会post上去,我们在post上面做文章
这里设置了长度。但是也不难,初学ctf的人应该都遇到过这个情况,改掉maxlength就行了。
输入"><script>alert(document.domain)</script><发现<>被过滤
这里我们换个思路,既然闭合不了就顺着他的意思,给他加个属性。
payload:
" onclick=alert(document.domain) id="a
这里可以知道和上节有点相似。但是按照上节的payload试试呢?
这里我们可以看到依然可以弹窗。但是和上节不同的地方就是value。上节中value并没有值,而这里有了。说明什么?
这里对"进行了过滤,所以这里的"能正确出现在框里面,当作value的值。上节中没有过滤"符号所以value值是空。
这里看到提示说用javascript协议。这里没有什么过滤直接xss
这里提示说要用utf-7的编码来绕过。并且目前只有IE7下才会成功。
payload构造参考的Nixawk的博客http://blog.csdn.net/nixawk/article/details/28038509
payload:
p1=a%2BACI++onmouseover%2BAD0AIg-javascript%3Aalert%28document.domain%29%2BACI++id%2BAD0AIg-x&charset=UTF-7
因为UTF-7编码需要结合utf-7bom,这部分不是很熟悉还需要学习一下。
这里我们可以看到对domain这个特殊字眼进行了过滤。
当我输入domain的时候发现对这个特殊字符串进行了识别然后替换成了空字符串。这样又一个简单的绕过方法,就是在domain中间加入一个domain。这种类似的方法sql中出现过很多次了。
paylaod:
"><script>alert(document.dodomainmain)</script>
script –> xscript script过滤成xscript
on[a-z] –> onxxx on事件过滤成onxxx
style –> stxxx style属性过滤成stxxx
但是没有过滤"<>这样的话就可以先闭合"><script>alert()</script>。但是这里过滤了script怎么办呢?
这个时候就可以想着对script就行编码就行了
那么该用什么编码呢?无非就是html实体编码,jsunicode,js16进制或者八进制,url编码。我们都试试。
html实体编码没有成功被解析
js16进制编码:
"><s\x63ript>alert(document.domain)</s\x63ript>
也是没有被解析
unicode:
"><s\u0063ript>alert(document.domain)</s\u0063ript>
也没有解析,url编码就不说了,也肯定是不会被解析的
那么这种对标签编码的方法是行不通的了。于是我们换个方法。既然script标签不行,我们还有javascript协议。我们用<a>标签去xss。
payload:
"><a href="javascript:alert(document.domain)">Da13</a>
但是还是得想办法绕过对script的过滤
按照之前的方法,我们先对某个字符进行html实体编码:payload:
"><a href="javascript:alert(document.domain)">Da13</a>
触发了。那我们缓缓js编码看看呢?
都没有成功。所以这里可以看出:
不能对标签编码,对javascript编码的时候首先是html解析起将实体编码识别,再是后面的url解析起识别a标签中的url编码,等到一切准备就绪。js解析开始识别最后的编码并触发弹窗
当然这题还有另一个解法:
paayload:
"><a href="javas	cript:alert(document.domain)">Da13</a>
"><a href="javas
cript:alert(document.domain)">Da13</a>
至于为什么在《XSS与字符编码的那些事儿》里面已经说到了。我这里就再做个搬运工。
过滤x00到x20所有字符,< > ” (英文双引号) ‘(英文单引号)。但是`还没被过滤,于是可以用`加上onclick,onmouseover,onfocus均可。但是前提只有在IE中才能实现。
payload:
``onclick=alert(document.domain);
根据提示,需要控制style的属性,style跟JS连接的属性有expression,url。需要注意的是expression是IE浏览器早期版本中的CSS属性值,实验使用IE 浏览器。
payload:
da13:expression(onmouseover=function(){alert(document.domain)})
和十三关没什么太大的区别,就是加了对敏感词汇的黑名单过滤
s/(url|script|eval|expression)/xxx/ig;
这样也不难绕过直接在关键词中间加注释符就行了。
这里可以看到时document.write()函数把value写入。我们先试试一般的payload看看。
可以看到这里对特殊符号进行了编码。导致我们输入的不能被触发
那我们试试编码html实体编码。
这里对&符号也编码了。
试试js十六进制编码
\x3cscript\x3ealert(document.domain);\x3c/script\x3e
这里可以看到成功了。就是因为document.write是js中的,所以按照js编码规则,这样的payload是可以被识别的。
这里可以看到依然是docment.write函数,但是做了过滤。"x"这类符号被过滤了,也就是说js的16进制都不行了。但是还有unicode编码和8进制,以下贴出unicode编码的payload。
payload:
\u003cscript\u003ealert(document.domain)\u003c/script\u003e
这里提示多字节字符。这里如果regist成功,输入的数据就会显示在框里面,如果有违法字符就什么都不会显示。这里fuzz以下发现过滤了"<>符号。根据提示可以猜测是类似于宽字节注入。
但是这里说是要老版本的IE才会成功。所以就直接贴出payload
payload:
p1=1%A7&p2=+onmouseover%3Dalert%28document.domain%29%3B+%A7
依然过滤了<>"
这个源自于浏览器会把一些8位的字符直接解释成7位ascii(漏洞已经在IE8中修补了)浏览器会忽略掉一些8位字符的第一位,如BC和<2进制的后7位相同,浏览器会把他当做BC,并不会过滤。比如:“<” 十六进制 “3C” ,对应二进制是 "0011 1100" 最高位置1 变为 1011 1100 — 也就是 BC。可以理解为 3C + 80 = BC (十六进制下)
所以
"><script>alert(document.domain)</scirpt>
经过变换后就是
%A2%BE%BCscript%BEalert(document.domain);%BC/scirpt%BE
这题也是需要IE才能实现
根据提示,可以找到该漏洞的文章
https://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html因为这个洞是2010年的了,比较久远了,而且要在IE8中才能触发。
这里和twitter中的漏洞环境差不多。取#!后面的放入linkurl后面。但是在谷歌里面插入
#!javascript:alert(document.domain)
本来在IE8中就可以弹窗但是这里看到谷歌会404,不过URL会变成javascript协议。
经过这次的xss challengs算是复习了一下对xss编码和简单xss绕过的一些小技巧,下来还会去练习一些更难的,灵活性更强的。希望各位大佬们如果看到什么
本文作者:星盟安全团队
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/123460.html