目录
一、存储型XSS原理
二、代码审计
三、第10关 存储型XSS注入实战
1.打开靶场
2.渗透实战
本文通过《Webug4.0通关笔记系列》来进行Webug4.0靶场的渗透实战,本文讲解Webug4.0靶场第10关存储型XSS的渗透实战。
一、存储型XSS原理
存储型XSS(Stored Cross-Site Scripting)是一种恶意脚本代码被永久存储在目标服务器上的XSS攻击类型。与反射型XSS不同,存储型XSS的攻击载荷会被持久化保存在服务器数据库中,当其他用户访问包含该恶意代码的页面时,攻击就会自动触发。存储型XSS攻击流程如下所示。
-
攻击入口点识别:攻击者首先寻找网站中允许用户输入并存储的内容区域,常见攻击点包括:
- 论坛帖子/评论系统
- 用户个人资料页
- 产品评价/留言板
-
恶意代码植入:攻击者在可输入字段中插入XSS载荷,例如:
<script>alert(document.cookie)</script>
-
服务器端存储:网站后端未进行充分过滤和转义,将含有恶意代码的内容存入数据库。
-
受害者访问触发:当其他用户浏览包含该恶意内容的页面时,浏览器会解析执行其中的恶意脚本,从而实现存储型XSS攻击。
二、代码审计
如下所示源码实现了一个带有安全防护机制的用户留言板功能,注释后的源码如下所示。
<?phprequire_once "../../common/common.php";// 会话验证:检查用户是否已登录,未登录则重定向到登录页面
if (!isset($_SESSION['user'])) {header("Location:../login.php");
}// 清除可能存在的xss2_flag Cookie(安全措施)
setcookie("xss2_flag", "", time() - 1);// 处理表单提交
if (isset($_POST["message"])) {if (!empty($_POST["message"])) {// 定义SQL关键词黑名单,防止SQL注入$filter = array('insert', 'update', 'select', 'delete', 'from');// 对用户输入进行预处理:转换小写并去除首尾空格$message = strtolower(trim($_POST["message"]));// 获取当前登录用户ID$userId = $_SESSION['user'];// 黑名单过滤:检测到敏感词时提示并终止if (in_array($message, $filter)) {echo "<script>alert('Please don\'t try to deposit dangerous characters')</script>";exit();} else {// XSS检测:如果输入包含"alert"字符串if (strstr($message, "alert")) {// 从数据库获取安全标志$s = "SELECT * FROM env_list WHERE id = 10";$r = $dbConnect->query($s);$w = mysqli_fetch_assoc($r);// 设置包含安全标志的Cookiesetcookie("xss2_flag", $w['envFlag']);}// 存在SQL注入的查询:直接将用户输入拼接到SQL语句中$sql = "INSERT INTO storage_xss(content, userId) VALUES('{$message}', '{$userId}')";$res = $dbConnectWidth->query($sql);}}
}// 查询当前用户存储的所有消息(存在SQL注入风险)
$sql1 = "SELECT * FROM storage_xss WHERE userId = '".$_SESSION['user']."'";
$res1 = $dbConnectWidth->query($sql1);// 引入HTML模板文件,显示用户消息
require_once TPMELATE."/xss_2.html";
代码实现了一个简单的留言存储功能,主要逻辑包括:
-
检查用户登录状态,未登录则跳转
-
清除名为
xss2_flag
的Cookie -
接收用户提交的
message
参数,进行简单的SQL关键字过滤(如select/insert等),这个过滤是为避免二次SQL注入进行filter处理(不过这个代码卡法这写的有问题,因为in_array函数的处理有问题,实际上也等于没有这个函数,基本上也无法过滤) -
如果
message
包含"alert"则设置包含敏感信息的Cookie,即当message包含alert关键字时,将flag写入到cookie中 -
将用户输入存储到数据库(将message信息存储到数据库中)并显示历史留言
如上所示存在存储型XSS注入,并可以通过将调用获取cookie的XSS注入语句实现注入,XSS注入的主要原因包括:
-
输入过滤不彻底:仅过滤部分SQL关键字(如select/insert)和"alert"字符串,未对HTML/JS特殊字符(如
<>'"
)进行编码或过滤 -
直接数据库存储:用户输入的原始
message
直接存入数据库,未做净化处理 -
未输出编码:在
xss_2.html
模板中直接输出数据库内容时,未使用htmlspecialchars
等函数进行编码 -
Cookie设置不安全:
setcookie
未设置HttpOnly/Secure属性,易被XSS窃取
三、第10关 存储型XSS注入实战
1.打开靶场
打开反射型靶场,如下所示此关卡有flag。
反射型XSS的网址如下所示。
http://192.168.71.1/webug4/control/xss/xss_2.php
页面打开后如下所示。
该界面具有迷惑性,鼠标一直向下滑会出现留言板界面, 根据经验这很可能是存储型XSS注入,具体如下所示。
2.渗透实战
构造包含alert的获取cookie的XSS注入命令。
<script>alert(document.cookie)</script>
在留言处进行注入并点击提交。
如下所示,通过XSS获取cookie得到了flag的值。
如上所示,flag获取成功。
xss2_flag=asdfsdfadfsdrew
将上一步获取到的flag值asdfsdfadfsdrew提交flag,效果如下所示。
如下所示提示flag正确,说明渗透成功。