XSS Challenges
XSS Challenges
Stage #1
http://xss-quiz.int21h.jp/?sid=e03ee5801343796c467d726953fb2a6b49f58006
观察变量
在search框中输入一个普通变量观察周围变量环境
由上图可见当我们任意输入aaa之后,审核元素可以发现输入的值写入到标签中
构造payload
由于是直接写入到b标签的内容里面,所以可以看出并没有对输入做任何过滤限制,于是可以直接构造js语句对其进行攻击
1
<b>"<script>alert(document.domain)</script>"</b>
我们这样做的目的只有一个,我们所提交的js参数要与周围环境和谐,浏览器才会对整个页面从新渲染,从而执行我们所提交的JS代码
Stage #2
http://xss-quiz.int21h.jp/stage2.php?sid=5068ea10a358df7653be0f031b52e6f43b6207cf
观察变量
在search同样输入普通变量aaa观察周围环境变量
可以看见这次我们输入的值,被传入了value值中,于是可以思考我们的js代码在input标签中,那么是否可以提前将input标签闭合,闭合后再传值作为内容部分,从而执行我们的JS代码
1
<input type="text" name="p1" size="50" value="<script>alert(document.domain)</script>">
构造payload
经过上面的分析我们可以构造js语句了(其核心思路就为根据提交和返回的值得关系,从而判断出提交规则,绕过)
1
"><script>alert(document.domain)</script>
Stage #3
http://xss-quiz.int21h.jp/stage-3.php?sid=ee0a5108164b4daae0a2afaeef662c7adf1c59e4
观察变量
这次当我们输入变量aaa之后,观察发现与stage #1类似,但事情估计不会那么简单
还是尝试着构造了一个payload试了一下,果然不行
1
<script>alert(1)</script>
失败原因:字符输入时被转义,可以看下关于PHP htmlspecialchars()的介绍
继续审核元素,发现后面有一个country也在b标签内,但在页面无法修改,改用抓包查看
发现请求的参数中有p2,从前面的审核元素中可以看见是属于country的,于是可以试着从p2入手
构造payload
将p2中的值修改为放包
成功执行
Stage #4
http://xss-quiz.int21h.jp/stage_4.php?sid=f5ecdd2b1ac189b0313a0395bba13c15ec23df4c
观察变量
同样输入一个普通常量aaa观察一下
发现这不就是上一关吗,于是按照正常逻辑,就不在此页面演示了,直接抓包改值
还是一样的直接修改p2的值,但是这次发现不行
想一想也是,毕竟是上升了一关了,于是发现在请求处符出现了一个p3,但这个p3=hackme,这个值并未在页面中出现,接着尝试修改了p3,发现还是不行,但此处通过抓包信息无法得出什么了,于是继续回到输入处,审核元素
发现修改p3的值,在页面处返回的信息中看见,我的js脚本是在input标签中,做到这里感觉不是跟stage #2一样吗,于是构造payload
构造payload
成功实现
3
Stage #5
http://xss-quiz.int21h.jp/stage--5.php?sid=3b204b3e8efd497a0a085f531ed716e828372d27
观察变量
- 同样输入一个普通观察元素
发现是在input标签中,跟第二关一样吗?,试一试
发现报错,点开查看,发现在value值后面输入的语句不完整,被自动裁掉了一半,发现前面有一个maxlength元素限制了长度
构造payload
修改maxlength的值,然后再构造闭合input标签的js语句
成功执行
Stage #6
http://xss-quiz.int21h.jp/stage-no6.php?sid=95f8ced6ca36ff11e4df12eec643be78224705fa
观察元素
还是一样的审核下元素,发现又是一样的,事情想也想得到不会这么简单,还是执行以下js语句看下怎么回事
插入js语句后发现字符转义了,<>被HTML特殊内容所代替
<img src="https://cdn.jsdelivr.net/gh/hang-thresh/imgbed/images/20210119142356.png" alt="image-20210115161703461" style="zoom:200%;" />
看到这,看了下提示event handler attributes(事件处理程序属性 ),提示我们要用事件属性来处理了
构造payload
根据提示,构造了如下js语句,具体可以看下onmouseover事件的用法,onclick等还有许多类似的用法
1
" onmouseover="alert(document.domain)
Stage #7
http://xss-quiz.int21h.jp/stage07.php?sid=0a0cc8b0b0c12ee8cd0590ce19865f165b628ad9
观察元素
输入一个普通元素看下elements,发现跟stage #2一样的情况,但有了stage #6前车之鉴,还是输入一下js语句,给他一个面子
执行语句之后,发现并未如同之前一样做什么转义,但发现我们输入的内容颜色(“ < >)好像不跟周围环境颜色相同,那么就只有可能我们传入的值成为了内容的一部分,也就是我们的”并未对value元素闭合,从而导致input标签也未被闭合,(“)发生了转义,我们传入的值未执行。
构造payload
有了上面的分析,基本可以有了一个方向,那就是让“不被转义,要让他执行,于是用对“进行utf编码一下,在放进去执行看看,发现还是没用
“还是被转义了,又尝试了下url编码绕过还是不行,最后百度了一下,发现可以通过可通过双引号后面加空格分隔属性,浏览器会自动补齐“,从而执行后面的语句,但在空格之前得输入一个值,然后空格输入,不然还是被当做是value中的传入,后面又发现同样对<>和/做了转义,于是还是参考stage #6的思路(不知道描述是否正确这一题)
1
1 onclick=alert(document.domain)
成功执行
Stage #8
http://xss-quiz.int21h.jp/stage008.php?sid=8e5137095794b899dbc36606cebfc1abc73498b2
观察变量
还是一样随机输入一个值,看看周围环境变量
发现是在一个a标签中,并且输入的值会显示在href和外面的内容中
那么就要在其中构造一个链接并弹出弹框来
构造payload
1
javascript:alert(document.domain)
javascript: 是一个伪协议
javascript:是表示在触发默认动作时,执行一段JavaScript代码,而 javascript:; 表示什么都不执行,这样点击时就没有任何反应。
成功执行
Stage #9
http://xss-quiz.int21h.jp/stage_09.php?sid=b96b4ca3bcd27679e5ab65d3a8200edf3f212d4e
观察变量
同样输入随机变量,观察下周围的环境变量
发现还是和之前一样,构造一个js语句试下,发现不行,语句没有闭合执行
于是用stage 7之前用到的payload试下
1
1 onclick=alert(document.domain)
发现没能通过,可直接看HTML的信息,发现和stage #7一样,一度怀疑自己前面错了,但后面想了下,对于xss双引号绕过,有很多不同的绕过放式,于是又试了下url编码、Unicode编码、HTML编码还是不对,于是又转到审核元素处,发现在input p1输入框下还有一个输入框,但页面没有显示,于是抓包看了下,发现是charset属性,又查了下euc-jp,是一种日文编码,于是应该是该文档的字符编码为euc-jp
payload构造
上面查看出了编码类型,但还是没找到太多关于euc-jp的利用,本想着构造一个反编码,奈何太菜,没实现
于是放弃了此题,后面查看了提示是utf-7,于是可能是跟utf-7有关,但还是没能实现。看了文章,一些大佬的笔记,大致如下
思路:
1.将payload构造成UTF-7编码
然后抓包改为如下
1
p1=1%2bACI- οnmοuseοver=%2bACI-alert(document.domain)%2bADsAIg- x=%2bACI-&charset=UTF-7
2.浏览器适应UTF-7,这里可以尝试一下,IEtester、ie7浏览器
具体做法就没尝试了,后面有时间在更新一下
Stage #10
http://xss-quiz.int21h.jp/stage00010.php?sid=9cead88514d9b964cca7ade5a16b96b883f9de9b
观察变量
还是同样的套路,输入一个普通常量,观察下周围的变量
不出意外还是自我感觉良好,和之前一样一步一步来吧
发现内容溢出了,而且还找不到domain不见了,于是双写domain尝试了下
1
"><script>alert(document.domaindomain)</script>
发现还是不行,那估计domain关键字被过滤了,试了下重写
1
"><script>alert(document.dodomainmain)</script>
成功执行
Stage #11
- 网址已无法打开
Stage #12
http://xss-quiz.int21h.jp/stage_no012.php?sid=491f61be10e2e4f1f9dc913f1bef5102ee7dd635
观察
- 还是老套路,先观察一番再说,看看周围环境变量
还是老惯例,基本不能闭合value来闭合表签绕过
但没办法,还是得输入进去,再看看具体情况
1
"><script>alert(document.domain)</script>
发现过滤了我们输入的”、<>
那么既然这样我们在stage #7中有一个类似的题,那么就用上面的playload去试一下
1
1 onclick=alert(document.domain)
发现并没有类似于之前的Stage #7,利用空格分隔了属性
构造payload
那么我们这个地方就只有一个目标将value属性闭合,但是又无法直接利用”,”是被直接过滤的,也就是应该无法利用编码之类的,想起了之前看xss绕过的一篇文章时,说道了可利用``代替”,去进行闭合,但是这是ie浏览器特性
成功
Stage #13
http://xss-quiz.int21h.jp/stage13_0.php?sid=39d578dbf7595d696ce798c5cab005b9fd12bf12
观察
还没开始输入就直接有个backgroud-color元素在里面
还是一样的就闭合value呗,老欺骗了
当执行常规js语句后,发现并没有起作用,可以看见颜色并没有发生变换,估计也是被过滤了,但上面有做过一个类似的题stage #7也是“被过滤,没起作用,构造了试了一下。还是没起作用
1
background-color:salmon onclick=alert(document.domain)
做到这其实也有点类似于上一题了,直接在ie浏览器上代替,但是估计还是不行
这不是没啥变换吗,题都升级了,总不可能绕过放式一样撒
果不其然,不得行,``失效了,估计在后端对此做了防御,有点无从下手了,看了下提示“style attribute”样式属性,百度了一下style xss,好像是带样式属性的xss攻击(并不是很清楚css特性),发现是利用css特性设置backgroud:url和javascript伪协议来做,难怪不得一进入13关就有background元素,对于这方面并不是很清楚吗,就直接利用payload了,但是值得注意的是必须要在低版本的ie浏览器下,才能执行,ie10以下,测试了ietester(需要安装f2插件)通过
1
background:url(javascript:alert('xss'))
Stage #14
http://xss-quiz.int21h.jp/stage-_-14.php?sid=452eceb5376523131d1711cb7b21e5db0de6130d
观察
还是如同13关一样一进去就是backgroud·····,那么就直接用13关的,先去IEtester,用了下13关的方法
可以发现url/script/eval/expression都被替换成xxx了,可以采用注释符打断
构造payload
1
xss:expres/**/sion(if(!window.x){alert(document.domain);window.x=1;})
有关于css expression的介绍可以看些这篇文章
Stage #15
http://xss-quiz.int21h.jp/stage__15.php?sid=1812d76c0cb38953e97626afc6cfca6bea4f9215
观察
还是一样提交普通变量看下外围环境
提交普通变量看下外围环境
发现第一处和第三处地方没变,第二处的地方发生了转义,HTML编码
那么试下以下js语句,看下第一处和第三处
1
"><script>alert(document.domain)</script>
这次得到的信息要多一点发现”也被转义了,除此外在另外两处中,”也被实体化了
也就是我们不能提交”、<>,那么用16进制提交试一下呢
1
2
3< 3c
> 3e
\x3cscript\3ealert(document.domain)\x3c/script\x3e
发现\被过滤了,再添加一个试一试
1
\\x3cscript\\3ealert(document.domain)\\x3c/script\\x3e
成功
这里主要利用了浏览器的特性,会自动转换16进制
后续
由于后续几关都涉及到浏览器的版本问题就没在继续闯关了
总结
一、主要思路:
1.看外围环境
2.提交普通变量观察周围环境 aaa
3.提交普通JS探测
1 | <script>alert(document.domain)</script> |
4.观察周围环境变量,看下返回参数
5.思考是否有转义字符,过滤,字符长度等
6.测试
7.构造payload
二、1-15关主要绕过放式
1.1-5关都是很基础的,只需要闭合标签就行或者寻找其他攻击点,基本没过滤,转义等,直接构造语句实现
2.第6关<>被转义利用事件属性完成 onmouseover、onclick等
3.第七关大体跟第6关一样,只不过”被实体化了,最后利用了双引号后面加空格分隔属性,浏览器自动补齐双引号完成绕过
4.第8关主要利用了JavaScript伪协议完成了绕过
5.第10关主要利用了重写绕过
6.第12关利用ie浏览器的特性``代替”绕过
7.第13关利用了css特性和javascript伪协议绕过,行内样式属性xss攻击
1 | background:url(javascript:alert('xss')) |
8.第14关主要利用了css expression加注释符打断绕过
1 | xss:expres/**/sion(if(!window.x){alert(document.domain);window.x=1;}) |
9.第15关主要利用了浏览器特性-自动解码16进制绕过
1 | \x3cscript\3ealert(document.domain)\x3c/script\x3e |
三、知识点
1.JS三种弹窗
alert()方法/警告框alert()
1
<script>alert(document.domain)</script>
confirm()方法/确认框confirm()
1
<script>confirm(document.domain)</script>
prompt()方法/提示框prompt()
1
<script>prompt("文本","默认值")</script>
SVG与XSS
1 | <svg/onload=alert(document.domain)> |
3.鼠标事件
因为上面有几关用到了鼠标事件,于是罗列了几个出来
onclick: 鼠标按下后松开才会触发
ondblclick:双击
onmousedown:按下 鼠标按下即可触发
onmouseenter:指针移动到元素上时触发
onmouseleave:指针移出元素时触发
onmousemove:指针进入后,在元素范围内,只要移动就会一直触发
onmouseover:移进去触发
onmouseout:移出时触发
onmouseup:鼠标进去后,按键松开时,触发一次
4.JavaScript伪协议
将JavaScript代码放在伪协议说明符javascript:后的url中,这样当加载这个url时,就会执行这个url中包含的JavaScript代码
1 | javascript:alert(document.domain) |