XSS_Lab笔记

XSS_Lab笔记

前言

XSSLab下载地址 do0dl3/xss-labs: xss 跨站漏洞平台 (github.com)

基础知识

JavaScript伪协议

text
"javascript:alert(1)"这样的是javascript伪协议。它的功能是将JavaScript:后面的语句当做JavaScript代码执行。
常常这样使用:
<a href="javascript:alert(1)">弹窗</a>
这个a被点击之后就会弹出alert对话框。

参考文章

xss-labs靶场实战全通关详细过程(xss靶场详解)-CSDN博客

XSS常见的触发标签_xss< img src onerror=alt=''+document.domain>”怎么触发-CSDN博客

闯关

我学习过程是先看着源码做一遍,然后总结方法。

level1

源码:level1.php

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

image-20240724131903086

解题

查看源代码知道是直接把 $_GET"name" echo出来。没有任何过滤。

答案是

level1.php?name=

level2

源码:level2.php

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

解题

image-20240724135602206

这里调用了htmlspecialchars()用于将特殊字符转换为 HTML 实体,以防止恶意代码注入和跨站脚本攻击(XSS)。

php
<?php
$str = "<script>alert(\"666\");</script>";
echo htmlspecialchars($str);
?>

上述的代码会输出

text
&lt;script&gt;alert(&quot;666&quot;);&lt;/script&gt;
  • < 转换为 '&lt;'
  • > 转换为 '&gt;'
  • & 转换为 '&amp;'
  • " 转换为 '&quot;' 可以通过参数取消转换。
  • ' 默认不会转化,需要额外的参数

详细参照php手册PHP: htmlspecialchars - Manual

转换后的字符在 HTML 中只会显示,不会执行。

但是这题有两个str拼接的地方

在value这里也拼接了str,可以从这里下手

image-20240724135655035

既然是拼接可以直接把前面的标签闭合之后插入任何html。

拼接法如下

text
<input name=keyword  value="
"> <script>alert()</script>
">

之后的结果是这样的,插入的内容把本来input的内容分成了两个部分。前一部分是提前闭合了的input,后面是插入的alert内容。

image-20240724140242019

在输入框输入

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

之后就过关了。

level3

源码:level3.php

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

解题

这一关两个拼接点都被转换了,没法直接放html标签(像<script><a>这样的)。

这关使用的方法是 事件绕过

HTML里有许多的事件。最常见的是onclick(点击事件)。举个例子

javascript
<p onclick="javascript:alert(1)">点我</p>
在p(文本段落标签)里绑定了onclick事件,所以点击p的时候会弹出alert。

既然无法通过标签<>添加新的html元素了,那就给input元素添加事件。

因为=是不会被转换的,所以大胆的绑定,双引号会被转换可以用单引号(因为htmlspecialchars不加ENT_NOQUOTES参数是不会转换单引号的。

input常用的事件如下:

事件名称事件解释
onfocus元素获得焦点时触发该事件。
onblur元素失去焦点时触发该事件。
onchange失去焦点时,元素的值发生改变时触发该事件。
oninput当元素的值发生输入时触发该事件。
onkeydown当按下键盘上的任意键时触发该事件。
onkeyup当释放键盘上的键时触发该事件。
onkeypress当按下键盘上的字符键时触发该事件。
onselect当选择元素中的文本时触发该事件。
onsubmit当提交表单时触发该事件。

什么是焦点?你把鼠标放上去点一下就是聚焦了。

其实html还有许多通用的事件,可以去学一学前端了解一下。

回归正题,构造payload

text
' onblur=javascript:alert(1) '

第一个单引号是和前面的"闭合,最后的单引号是为了和后面的"闭合。

输入完之后,点一下文本框聚焦,然后再点一下外边空白就失去了焦点就触发alert了。

level4

源码:level4.php

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

解题

这关是用str_replace把 < 和 > 替换成空字符了。依然不能用添加新元素的方式。和上一关一样。

做到这我有点疑惑,这关比上一关过滤的少,只过滤了<>。这关和上一关是有啥其他的方法吗我没用到吗?

level5

源码:level5.php

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

解题

这题我看方法挺多的。

level6

源码:level6.php

level7

源码:level7.php

level8

源码:level8.php

level9

源码:level9.php

level10

源码:level10.php

level11

源码:level11.php

level12

源码:level12.php

level13

源码:level13.php

level14

源码:level14.php

php
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>欢迎来到level14</title>
</head>
<body>
<h1 align=center>欢迎来到level14</h1>
<center><iframe name="leftframe" marginwidth=10 marginheight=10 src="http://www.exifviewer.org/" frameborder=no width="80%" scrolling="no" height=80%></iframe></center><center>这关成功后不会自动跳转。成功者<a href=/xss/level15.php?src=1.gif>点我进level15</a></center>
</body>
</html>

level15

源码:level15.php

php
<html ng-app>
<head>
        <meta charset="utf-8">
        <script src="angular.min.js"></script>
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.location.href="level16.php?keyword=test"; 
}
</script>
<title>欢迎来到level15</title>
</head>
<h1 align=center>欢迎来到第15关,自己想个办法走出去吧!</h1>
<p align=center><img src=level15.png></p>
<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>



level16

源码:level16.php

php
<!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="level17.php?arg01=a&arg02=b"; 
}
</script>
<title>欢迎来到level16</title>
</head>
<body>
<h1 align=center>欢迎来到level16</h1>
<?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>";
?>
</body>
</html>


level17

源码:level17.php

php
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!"); 
}
</script>
<title>欢迎来到level17</title>
</head>
<body>
<h1 align=center>欢迎来到level17</h1>
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
<h2 align=center>成功后,<a href=level18.php?arg01=a&arg02=b>点我进入下一关</a></h2>
</body>
</html>







level18

源码:level18.php

php
<!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="level19.php?arg01=a&arg02=b"; 
}
</script>
<title>欢迎来到level18</title>
</head>
<body>
<h1 align=center>欢迎来到level18</h1>
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
</body>
</html>




level19

源码:level19.php

php
<!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="level20.php?arg01=a&arg02=b"; 
}
</script>
<title>欢迎来到level19</title>
</head>
<body>
<h1 align=center>欢迎来到level19</h1>
<?php
ini_set("display_errors", 0);
echo '<embed src="xsf03.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>
</body>
</html>



level20

源码:level20.php

php
<!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="level21.php?arg01=a&arg02=b"; 
}
</script>
<title>欢迎来到level20</title>
</head>
<body>
<h1 align=center>欢迎来到level20</h1>
<?php
ini_set("display_errors", 0);
echo '<embed src="xsf04.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>
</body>
</html>


总结

事件绕过

Linux的bash下建立TCP连接发送http请求
🪄UbuntuServer的sudo命令响应很慢原因和解决办法

评论区

评论加载中...