漏洞原理,看这里哇
目录
xss-labs
文章所用的xss-labs靶场的项目地址:https://github.com/do0dl3/xss-labs
然后开始通关

level1

仔细观察三处箭头,可以发现它是向服务器提交了一个name参数,值为“test”,从页面
回显来看,将neme参数的值显示在了页面上,并且显示了name参数值的字符长度
接下来,查看源码

从这里我们可以看到它将name的参数值,插入到了<h2> </h2>标签之间
那么 就很明显,这一关主要就是考察反射型xss
但是由于不知道服务器端对于提交的敏感字符有没有过滤,所以这里直接在name参数
中赋值一个简单的弹窗来进行测试。
操作如下:
将name参数重新赋值:<script>alert('xss')</script>

我们可以看到用于js弹窗的代码顺利执行了
那么这段代码在网页中如何显示的 呢

可以看到服务器是将我们的恶意代码原封不动的返回了,浏览器才能成功弹窗
可以去看看服务器端的level1.php如何对参数操作的

从源码可以看出,箭头1将从服务器获得的name参数的值赋值给str变量,箭头二又将
str变量直接插入到<h2> </h2>标签之间
因此服务器并没有对name参数的值进行严格的管理,并且这个值还是用户可控的,所
以存在反射型xss漏洞
点击确定可以来到第二关
level2

从url入手开始看,依然是get方式传递参数,应该还是反射型xss
只不过这一关加入了“输入框”和“搜索”
接下来查看网页源码

从源码来看,它的功能就是通过点击“搜索”按钮,将输入框内的内容以get方式提交给
服务器上的level2.php
经过服务器的动态处理之后又会将参数keyword的值插入到<h2> </h2>标签之中以及
添加到<input>标签中的value属性的值内。
尝试使用上一关的恶意语句操作进行弹窗

但是报错了
我们继续查看网页源码

可以看到在<h2> </h2>标签之中的恶意代码被编码了。
其中<和>都被编码成了html字符实体。
猜测在服务器端用htmlspecialchars()函数对keyword参数的值进行了处理。
接着往下看可以看到插入到value参数值中的恶意代码并没有被编码而是直接原样返回
但是问题是这里的js代码在标签属性值中,浏览器是无法执行的。
既然上面的恶意代码被编码了,那么只能从属性值中的恶意代码处进行突破了。
要想浏览器执行这里的弹窗代码,只需要将属性的引号和标签先闭合就可以了。
将keyword的参数值重新赋值"><script>alert('xss')</script>//

左边的">去闭合原先的"
右边的//去注释原先的">
可以看到浏览器成功弹窗了,说明我们提交的恶意代码被浏览器执行了。
去服务器端看看level2.php代码

箭头1处将get方式传递到服务器端的keyword参数的值赋给str变量。
在箭头2处是用htmlspecialchars()函数对变量str进行处理之后显示到网页上。
在箭头3处却是直接将变量值插入到了<input>标签的value属性值中
因为这里并没有对敏感字符进行编码和过滤,所以可以通过构造实现XSS攻击。
level3
在输入框输入“test” 进行尝试一下
看看网页源码

与第二关相似
但是还不确定有没有敏感字符过滤,编码等操作
构造弹窗测试一下

报错了
继续看看网页源码

这两处都将<和>这样的敏感字符编码成了html字符实体。
猜测服务器端在这两处都用htmlspecialchars()函数进行了处理。
去服务器端看看level3.php代码

确认我们的猜测
这里可以通过<input>标签的一些特殊事件来执行js代码
构造代码:level3.php?keyword='onfocus=javascript:alert('xss') > //&submit=搜索

发现没有直接弹窗,这是因为onfocus事件的特殊性造成的
onfocus 事件在对象获得焦点时发生。
onfocus 通常用于 <input>, <select>, 和<a>.
最简单的实例就是网页上的一个输入框,当使用鼠标点击该输入框时输入框被选中可以
输入内容的时候就是该输入框获得焦点的时候,此时输入框就会触发onfocus事件.因此
点击当前页面的输入框就可以完成弹框了。

level4

这一关很明显还是用的get方式请求参数
并且该参数值在页面上有两处显示
上弹窗代码测试一下

输入框中与我们提交的参数值有出入,<和>没有了
看看网页源码

箭头1处直接将<和>编码转换了
箭头2处却是把<和>删除了
但是,事件触发却不需要使用这两个符号。
用上一关的代码:level4.php?keyword="onfocus=javascript:alert('xss')"
在点击输入框之后成功触发了事件进行弹窗。

看看源码 分析一下

箭头1:将get方式传递到服务器端的keyword参数的值赋给str变量。
箭头2和3:将变量中的<和>删除
箭头4:对变量进行编码然后显示在页面上
箭头5:将去除<和>的变量值插入到<input>标签的value属性值中。
level5

分析图片,还是get方式请求参数,所以还是反射型的xss
上弹窗代码:<script>alert('xss')</script>测试一下

报错了 在我的意料之中。。。
看看网页源码

箭头1处:应该是被htmlspecialchars()函数将<和>进行了编码处理
箭头2处:在显示位可以看到,它在我们的恶意代码<script>中添加了一个_符号
用之前事件触发的代码进行测试:?keyword="onfocus=javascript:alert('xss')>//

但是这次却没有成功触发弹窗
继续看看网页源码

这里居然对onfocus这一类的事件字符也进行了防范。
从刚才的响应来看提交的javascript字符并没有被过滤或者转义等
所以此处既然无法通过<script>标签或触发事件来执行js代码的话,那么可以换一个标
签来执行js代码。
继续构造如下代码:?keyword="> <a href=javascript:alert('xss') > xss</a> //

从页面回显可以看到一个xss的链接
点击链接即可触发弹窗的js代码

接下来去服务器端看看这一关的源码

箭头1:将get方式传递到服务器端的keyword参数的值进行全小写的转换,然后赋值给str变量。
箭头2和3:通过str_replace()函数来破坏变量值中的敏感字符的语义。
箭头4:通过htmlspecialchars()函数处理之后显示到网页上,
箭头5:直接将进行敏感字符处理之后的变量值插入到<input>标签的value属性值中。
level6
上test字符看看情况:?keyword=test&submit=搜索

在看看网页源码

和之前好像没有没有区别
都是一个在<h2> </h2>标签之内,另一个在value属性中
接下来尝试恶意代码:<script>alert(‘xss’)</script>

意料之中的报错
继续看看网页源码

上面则还是<和>被编码了
下面则是在script字符中插入_破坏语义。
尝试事件触发的代码进行尝试:?keyword="onfocus=javascript:alert('xss')"
可以看到在value属性值中也插入了_符号防止xss的发生
尝试上一关的<a>标签:?keyword="> <a href=javascript:alert('xss') > xss</a> //
也报错了

查看代码后也是一样的原因
有点慌,我们可以试试大小写混写来尝试能不能绕过
还是标签:?keyword="> <a HrEf=javascript:alert('xss') > xss</a> //

同样还是点击了页面回显的xss链接
我们这里改动的是<a>标签中的href属性的大小写,而在html中对大小写是
不敏感的。
接下来看看服务器端这一关的源码

从源码来看,服务器端做的防范措施比我们想的要多
箭头1:将get方式传递到服务器端的keyword参数的值赋值给str变量。
箭头2:用字符<script去匹配我们提交的参数值,如果匹配到了就进行替
换来破坏原来的语义导致无法实现xss。
此处能够防范的是<script> </script>这一类的恶意代码。
箭头3:可以看到是用字符on去匹配参数值,如果匹配到了就进行替换
破坏原有语义。
这里主要防范的是利用带有on字符的事件来触发恶意代码
比如前面用到过的onfocus事件。
箭头4:可以看到是用字符src去进行匹配
得提到<img>标签了。
熟悉html的人都会知道在<img>标签中引用图片会用到一个属性就是src。正常的引用图
片就是将待引用图片的地址赋值给src属性。但是在js中如果src属性的值不正常或者无法
访问到时就可以触发一个onerror事件来执行js代码。
<img>标签代码:?name=<img src=111 onerror=alert('xss')>
箭头5:用字符data进行匹配的,同上面一样该字符在之前的演示中也没有
出现过。现在一般有点XSS意识的管理员都懂得过滤javascript与script等关
键字。但是对于data的认识却并不多,也就很少有对它进行过滤的。
Data在我看来就是对字符进行编码的一种设定,比如如果在实际情况中
javascript、script等关键字被过滤掉了之后,可以用如下语句进行尝试
data:text/html;base64,PHNjcmlwdD5hbGVydCgieHNzIik8L3NjcmlwdD4=
这条语句
和javascript:alert("xss") 或者 <script>alert("xss")</script> 的作用是一样的。
箭头6:可以看到是用<a> </a>标签中的字符href来进行匹配了,防止的
就是通过在href属性中插入js代码来点击执行。
箭头7:用htmlspecialchars()函数对变量str进行处理后显示到网页上。
箭头8:直接将str变量值插入到了标签的value属性值中
level7
上<script>alert('xss')</script>代码测试一下

看看网页源码

箭头1:将<和>进行编码处理了
箭头2:把script字符直接删除了
再试试事件触发:?keyword="onfocus=javascript:alert('xss')//

可以看到onfocus事件直接把on字符删除了,javascript中的script字符也被删除了。如果是这样的话就不需要再继续尝试新的标签了,看看前面的大小写能不能绕过

大小写绕过失败,尝试双写关键字

看看网页源码

箭头1:对参数值转换成了小写
箭头2:将基本的关键字都删除了,但是它只执行了一次 所以可以双写绕过
level8
第8关 与之前有些区别
用test测试,查看源码

提交的参数值一个会插入到<input>标签的value属性值中,
一个会插入到下方<a>标签的href属性值中。
测试服务器对客户端的处理
1.<script>alert('xss')</script>&submit=添加友情链接

<和>被编码了
在href属性值中script字符被插入了_字符破坏语义
2.事件触发测试:?keyword=" onfocus=javascript:alert('xss')>//&submit=添加友情链接

用来闭合引号的引号也被编码了。
onfocus一类的事件也被破坏了
大小写绕过,失败了
因为此处没有对关键字进行删除,所以就不进行双写测试了
其实还可以将我们要提交的js代码进行编码

看看网页源码

在去服务器端看看这一关的源码

箭头1:对参数值做了小写处理
箭头2:对常见的关键字做了过滤处理
箭头3:将用来起闭合作用的引号做了字符实体替换。
level9
看看网页源码

提交的参数值插入到了标签的value属性值中
但是在<a>标签的href属性中却并没有出现该参数值,
而是显示的 "您的链接不合法?有没有!"这样的字符串。
猜测这里可能对url地址做了匹配。
只有包含正常的url地址才能添加到href属性值中
构造一个有正常url地址的恶意代码:
?keyword=javascript:alert('xss')http://www.baidu.com

语句虽然显示在了href属性值中,但是javascript字符被插入了_
尝试用大小写绕过试试

然而并没有成功
那么尝试对关键字进行编码

还是相同的编码

http://www.baidu.com之间需要插入//,否则不会成功执行弹窗。
去服务器端看看这一关的源文件代码

箭头1:与上一关一致
箭头2和3:判断如果字符中没有http://的话就会返回false,
接着在href属性值中就会出现"您的链接不合法?有没有!"
箭头4和5:判断成功后,返回第一次出现的位置,
将该字符插入到href属性值中了
level10
与之前又不一样了
看看网页源码

在源码中有一个隐藏的表单。
其中含有t_link t_history t_sort这样三个隐藏的<input>标签
先测试一下

看看网页代码
这里有三个<input>标签的话,也就意味着是三个参数
看看哪一个标签能够被突破
构造语句:
?keyword=<script>alert('xss')</script>&t_link=" type="text"&t_history=" type="text"&t_sort=" type="text"

从页面响应来看,有一个<input>标签的状态可以被改变。这个标签就是名
为t_sort的<input>标签,之前都是隐藏状态,但是通过构造参数响应发现只
有它里面的值被改变了。
因此可以从该标签进行突破,尝试能不能注入恶意代码进行弹窗。
构造如下代码:
?keyword=<script>alert('xss')</script>&t_sort=" type="text" onclick="alert('xss')

看看源码

箭头1:说明是接收t_sort参数值的。
箭头2:会删除t_sort参数值中的<和>。
从这里来看的话这一关就只能是将js代码插入到<input>标签的属性值中来执
行而不能通过闭合<input>标签引入新的标签来触发xss了。
level11

看看网页源码

可以看到如同第十关一样有隐藏的表单
不同的是多了一个名为t_ref的<input>标签。
尝试用上一关的方法看看能不能从这几个标签进行突破注入代码。
构造代码
?keyword=good job!&t_link="type="text&t_history="type="text&t_sort="type="text&t_ref="type="text

页面没有反应
看看网页源码

原来t_sort仍然是接受参数值的,但是里面的双引号被编码了
这样浏览器只能正常显示字符但是却无法起到闭合的作用了。
进行抓包
可以看到在原始的请求数据包中并没有referer这个请求头,那么我们可以自
己给它加上

referer:111

构造代码
referer:"type="text" onclick="alert('xss')

可以看到我们添加的referer头的值出现在了t_ref标签的value属性值中了。
接下来就是从这里突破注入恶意代码了,恶意代码成功插入了value属性值
中,接着将这个请求的响应放行到浏览器试试
成功弹窗了,说明通过referer头来提交恶意代码触发了xss
去服务器端看看源码

在服务器端还将请求头中的referer头的值赋给了str11这个变量,在将变量
值中的<和>删除之后就会插入到t_ref这个标签的value属性值中。而
上一关的t_sort标签虽然也能接收并显示参数值,但是这个参数值是要用
htmlspecialchars()函数处理的。
level12

看看网页源码
看到了t_ua这样一个标签,并且其中的value属性的值怎么看起来那么
像抓取数据包中User-Agent头的值?!
尝试先抓包试试

果然两个值是一模一样的。
那么接下来尝试先闭合前面的value属性,然后构造恶意代码看看
"type="text" onclick="alert('xss')

放行响应数据包到浏览器即可通关
去服务器端看看源代码

将keyword参数的值赋给了变量str
将t_sot参数的值赋给了变量str00,
将请求中User-Agent头的值赋给了变量str11,。
将变量str11的值中存在的<和>删除之后直接插入到了t_ua标签的value
属性值中。
在这里变量str和str00的值都是需要被htmlspecialchars()函数处理过
才能返回给浏览器。
level13
与之前几关很相似
看看网页源码

出现了一个新的标签
猜这里应该还是跟http请求头有关
抓包测试一下

可以看到抓取的数据包中cookie头是有值的,而且这个值在响应的网页
源码中的t_cook标签中出现了。
尝试在cookie的值中进行构造语句
"type="text" onclick="alert('xss')

放行响应数据包到浏览器即可通关
level14
本关因iframe调用的文件地址失效,无法进行测试。
要考的应该是通过修改iframe调用的文件来实现xss注入
略
15关

看看网页源码
可以看到我们提交的参数src的值被插入到了<span>标签的class属
性值中,但是前面还有ng-include这样的字符。
ng-include是angular js中的东西,其作用相当于php的include函数。这里就
是将1.gif这个文件给包含进来。
先尝试看看能不能直接闭合标签来触发弹窗

可以看到一些字符被编码了。
先看看源文件的代码

src地址无法访问
先将其换成国内可以访问的地址:
https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js
既然此处用了ng-include指令的话,先了解一下其具体的用法。
1、ng-include 指令用于包含外部的 HTML文件。
2、包含的内容将作为指定元素的子节点。
3、ng-include 属性的值可以是一个表达式,返回一个文件名。
4、默认情况下,包含的文件需要包含在同一个域名下。
特别值得注意的几点如下:
1.ng-include,如果单纯指定地址,必须要加引号
2.ng-include,加载外部html,script标签中的内容不执行
3.ng-include,加载外部html中含有style标签样式可以识别
既然这里可以包含html文件,那么也就可以包含之前有过xss漏洞的源文件
构造代码:
?src='level1.php?name=<img src=1 onerror=alert(1)>'
因为这里参数值算是一个地址,所以需要添加引号。
但是level1.php不是一个php文件吗?
这里解释一下
这是因为我们不是单纯的去包含level1.php,而是在后面添加了name参
数值的。这就有点像是在访问了该参数值中地址之后把它响应在浏览器端的
html文件给包含进来的意思。
然后尝试一下
构造代码
?src='level1.php?name=<img src=1 onerror=alert(1)>'
成功弹窗了!

level16
可以看到我们提交的参数值在页面中有一处显示位
看看网页源码

并没有什么特殊的地方,只是参数值被插入到了<center>标签中。
用最基本的弹窗代码测试一下

关键字script以及 / 和空格都被编码成同样的空格字符实体了。
这样也没办法去闭合前面的标签了。
看看源文件的代码

箭头1:将参数值中的script替换成
箭头2:将参数值中的空格也替换成
箭头3:将参数值中的/符号替换成
与我们的猜想一致
绕过思路:可以用回车来将它们分开。
而且这里/符号也被编码了,所以我们需要的是一个不需要闭合的标签,比
如之前所用过的<img>
构造语句:
<img
src=”111”
onerror=alert(‘xss’)
>
回车可以用url编码格式%0a来表示
成功弹窗

level17

这一关看着很简单,有点诡异
因为中间有一个flash没法正常显示出来。。。
看看网页源码

我们提交的两个参数的值出现在了<embed>标签的src属性值中
猜测该标签应该就是突破口,然后用基本的弹窗代码测试

可以看到我们构造的代码中关键字都被编码了,
这里应该被htmlspecialchars()函数处理过的。仔细观察一下发现这个
<embed>标签就是引入一个swf文件到浏览器端,并且它的src属性值没
有添加引号,所以不用闭合

中间出现了一个类似于图片的东西。
所以这里可以考虑通过事件来触发。
比如此处可以用onclick事件测试一下
onclick=alert('xss')

点击页面响应中显示该swf文件区域的时候成功弹窗
还有其他事件可以触发
比如
onmouseover:(表示当鼠标移动到该标签上时就会触发执行某项动作)。
看看源文件的代码

在服务器端上传的两个参数的值都用htmlspecialchars()函数进行了处理
level18

看到浏览器传递了两个参数值,但是在响应的页面中只是显示了一个flash的
文件。
看看网页源码

看到传递的两个参数值也是出现在了<embed>标签的src属性值中
用上一关的方法:onclick事件测试一下
onclick=alert('xss')

成功插入到标签之中,完成弹窗
去服务器端看看源码

与上一关一致。。
level19

看看网页源码
src的值使用双引号括起来的。
如果想要成功执行js代码肯定需要去闭合标签,但是此处应该还是会用
htmlspecialchars()函数进行处理,所以无法成功闭合。
这一关涉及一种xss攻击手段叫做flash xss
Flash产生的xss问题主要有两种方式:
加载第三方资源
与javascript通信引发XSS。
常见的可触发xss的危险函数有:
getURL navigateToURL ExternalInterface.call htmlText loadMovie等
要想知道这一关的是不是属于flash xss,只需要对引用的swf文件
进行反编译然后进行源码分析。
这里我说使用的对此类文件进行反编译的工具是jpexs-decompiler。
项目地址:https://github.com/jindrapetrik/jpexs-decompiler
flash xss最后还是没闹懂。。。
插入个链接,大家先看看https://www.freebuf.com/sectool/108568.html
level19和level20 略。。。
本文详细介绍了xss-labs的各个关卡,从level1到level19,分析了每个关卡的漏洞原理和解决方法,包括反射型XSS、编码绕过、事件触发等技巧,通过实例展示了如何利用这些技巧通关。

4005

被折叠的 条评论
为什么被折叠?



