http://test.xss.tv
http://47.94.13.75/test/
test on Firefox 54.0 (64-bit)
Level1
1 2 3 4 5 6
| view-source:http: <h2 align=center>欢迎用户test</h2> 直接在文本中输出用户提交的变量 http:
收获:为HTML body添加标签。
|
Level2
1 2 3 4 5 6
| view-source:http: <input name=keyword value="test"> 直接在标签属性中用户提交的变量 http:
收获:闭合标签属性的双引号、闭合标签并在标签外添加script标签。
|
Level3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| view-source:http: <h2 align=center>没有找到和';!-"<findneo>={()}/\&相关的结果.</h2> <input name=keyword value='';!-"<findneo>={()}/\&'>
两处输出都对双引号、尖括号和&进行了HTML实体编码,但前面的单引号可以被闭合,考虑使用input标签的某些事件执行脚本。 自动聚焦到输入框,打开就弹 http: 点击页面非输入框的任何地方以移开焦点 http: 点击输入框 http: http: 在输入框输入 http: 输入然后点击搜索 http: 移动鼠标经过输入框 http: http: http: 点击输入框,进行按键操作 http: http: http: 双击输入框 http:
更多可用事件可以参考这里:https:
收获:闭合标签属性的单引号并在标签中添加事件。
|
Level4
1 2 3 4 5 6 7 8 9
| view-source:http: <h2 align=center>没有找到和';!-"<findneo>={()}/\&相关的结果.</h2> <input name=keyword value="';!-"findneo={()}/\&">
在文本中编码了双引号、尖括号和&,在标签属性值中过滤了尖括号。 把上一题payload的单引号换成双引号应该都可以用 http:
收获:闭合标签属性的双引号并在标签中添加事件。
|
Level5
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| view-source:http: <h2 align=center>没有找到和';!-"<findneo>={()}/\&相关的结果.</h2> <input name=keyword value="';!-"<findneo>={()}/\&">
在文本中编码了双引号、尖括号和&,标签属性值没有编码 进一步测试发现query会转成小写,<script,on等敏感词会加下划线 看起来事件和script标签都不好使,可以闭合原来的标签,自己添加标签,然后试着用用刚从书里学到的伪协议 点击findneo就能弹 http: 做一下美化 http: vbscript和dataURI似乎都不能奏效。
收获:利用JavaScript伪协议。
|
Level6
1 2 3 4 5 6 7 8 9 10 11 12 13
| http:
<h2 align=center>没有找到和';!-findneo={()}/\相关的结果.</h2>
<input name=keyword value="';!-"<findneo>={()}/\&">
在文本中编码了双引号、尖括号和&,标签值属性没有编码
进一步测试发现<script,on,href都被加下划线了,但是没有做全部转小写的操作,所以可以大小写绕过。
http:
收获:大小写绕过敏感词检测。
|
Level7
1 2 3 4 5 6 7 8 9
| view-source:http: <h2 align=center>没有找到和';!-"<findneo>={()}/\&相关的结果.</h2> <input name=keyword value="';!-"<findneo>={()}/\&">
在文本中编码了双引号、尖括号和&,标签值属性没有编码 进一步测试发现on,script,href都被替换为空,但只执行一次,没有递归操作,可以用关键字嵌套来绕过。 http:
收获:关键字嵌套(双写)绕过敏感词过滤。
|
Level8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| view-source:http: <input name=keyword value="';!-"<findneo>={()}/\&"> <a href="';!-"<findneo>={()}/\&">友情链接</a>
input标签的value属性输出处编码了双引号、尖括号和&;a标签的href属性输出处编码了双引号。 进一步测试发现数据都被转小写,on,script,href,data等都被加下划线了。 一番查找资料发现了可以通过JavaScript变换(利用空白符如水平制表符HT,换行符LF,回车键CR来截断关键字)的办法绕过 http: http: http:
可在http: 页面内搜索“JavaScript变换”看到相关信息。
收获:空白符(特殊的结束标识符)绕过敏感词检测。
|
Level9
1 2 3 4 5 6 7 8 9 10
| view-source:http: <input name=keyword value="http://';!-"<findneo>={()}/\&"> </center><center><BR><a href="http://';!-"<findneo>={()}/\&">友情链接</a>
输入数据全部转为小写,且必须协议正确,刚开始以为必须以“http://”开头,后来发现只要含有就可以了。 input标签的值编码了双引号、尖括号和&;href处编码了双括号。 从上一题稍作变化即可 http://47.94.13.75/test/level9.php?keyword=javas%09cript:alert('http://')
收获:如果要检测URL协议,应该检测协议名是否在字符串的开头。
|
Level10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| view-source:http: <h2 align=center>没有找到和';!-"<findneo>={()}/\&相关的结果.</h2> 只有一个输出点,编码了双引号、尖括号和&。谷歌了很久,都说这几乎是不可能成的。(If angle brackets and double quote characters are escaped, this is enough to prevent XSS in HTML body and double quoted entity value contexts.) 无奈之下查了writeup,发现自己观察能力需要提高,显著的hidden就在眼皮底下,竟然一点都没有注意到。 有一个隐藏的表单如下: <form id=search> <input name="t_link" value="" type="hidden"> <input name="t_history" value="" type="hidden"> <input name="t_sort" value="" type="hidden"> </form> 可尝试其参数是否可能被注入 访问47.94.13.75/test/level10.php?keyword=asdf&t_link="&t_history="&t_sort=" 会发现在相应中t_sort是可注入双引号的,于是可以构造链接弹窗。 http://47.94.13.75/test/level10.php?t_sort=" autofocus onfocus=alert() type="text
收获:注意测试隐藏元素。 这道题乍一看有些让人摸不着头脑,但仔细想想觉得这在真实环境中是会发生的。开发者利用隐藏的表单提交数据,然后就默认这些数据是可靠的,于是在忘记或者认为没必要在服务端做校验,这就导致了代码的缺陷。像本题的t_sort键就是个例子,所以如果遇到hidden的元素可以测一测。
|
Level11
1 2 3 4 5 6 7 8 9
| test1:view-source:http: 与上一题类似,表单中多了一个t_ref,但看起来只有t_sort可以注入。 test2:view-source:http: 得到:<input name="t_sort" value="';!-"<findneo>={()}/\&" type="hidden"> 对双引号、尖括号和&进行了编码。input标签中value属性的双引号难以逃逸。 考虑莫名多出来的t_ref,猜测服务端是取请求头的referer值来返回,于是截包添加请求头。 referer: " autofocus onfocus=alert() type="text
收获:寻找一些可能的、可控的输入!
|
Level12
1 2 3 4
| view-source:http: 与上一题相似,这题修改的是UA。
收获:User-Agent(以及HTTP请求头的其他部分)也是可控的输入。
|
Level13
1 2 3 4
| view-source:http: 与前面类似,修改Cookie。
收获:Cookie(以及HTTP请求头的其他部分)也是可控的输入。
|
Level16
1 2 3 4 5 6
| http: 测试发现编码了/和空格 将后面内容注释掉,使用无需闭合的标签,使用特殊空白符代替空格即可 http:
收获:注释符,空白符
|