当前位置: 首页 > news >正文

DVWA靶场通关笔记-存储型XSS(Stored Impossible级别)

目录

一、存储型XSS

二、源码分析

1、index.php

2、Impossible.php

3、htmlspecialchars功能函数

三、存储型XSS安全级别分析

1、Low 级别

2、Medium 级别

3、High 级别

4、Impossible 级别

四、Impossble防范分析

1、防 CSRF 令牌验证

2、输入去斜杠处理

3、SQL 注入防护

 4、数据库预处理语句

5、htmlspecialchars防护


本系列为通过《DVWA靶场通关笔记》的存储型XSS关卡(low,medium,high,impossible共4关)渗透集合,通过对相应关卡源码的代码审计找到讲解渗透原理并进行渗透实践。本文为存储型XSS impossible关卡的原理分析部分,讲解相对于low、medium和high级别,为何对其进行渗透测试是Impossible的。

一、存储型XSS

存储型XSSStored Cross-Site Scripting是恶意脚本被持久化保存到服务器(如数据库、文件等),当其他用户访问包含该脚本的页面时自动执行。常见于留言板、评论系统等用户提交内容被展示的场景。相对于上一章节的反射型XSS,存储型XSS与反射型XSS的主要区别如下所示。

对比项存储型 XSS反射型 XSS
攻击向量存储恶意脚本存储在目标服务器(如数据库)恶意脚本仅在 URL 参数等地方,不存储在服务器
触发条件受害者访问包含恶意脚本的页面(如论坛帖子)受害者点击特制链接或提交含恶意代码的表单
持久性长期有效,直到内容被管理员删除单次有效,仅当前请求 - 响应周期生效
传播范围影响所有访问该页面的用户仅影响点击链接的特定用户
典型场景评论区、留言板、用户资料等搜索结果、错误提示、登录表单反馈等
防御重点严格过滤用户输入并转义输出内容对 URL 参数等外部输入进行严格校验和编码

二、源码分析

1、index.php

进入DVWA靶场源目录,找到index.php源码,如下所示。

这段代码是DVWA(Damn Vulnerable Web Application)中存储型XSS关卡的演示页面,主要功能包括:初始化DVWA环境、连接数据库、提供留言板表单(包含姓名和消息输入字段)、根据安全等级(low/medium/high/impossible)加载不同的处理逻辑、支持清空留言板(TRUNCATE),并在页面上显示留言内容和相关参考资料。代码的处理逻辑具体如下所示。

  • 环境初始化:设置路径常量,加载DVWA核心文件,启动会话和PHPIDS安全检测。
  • 页面配置:设置页面标题、ID及帮助按钮。
  • 数据库连接:dvwaDatabaseConnect() 建立MySQL连接。
  • 清空留言板:通过TRUNCATE语句清除所有留言(触发条件:btnClear提交)。
  • 安全等级控制:根据Cookie中的security值加载对应的级别文件(low.php/medium.php/high.php/impossible.php)。
  • 留言板表单:提供姓名(txtName,限10字符)和消息(mtxMessage,限50字符)的输入字段。
  • CSRF防护:仅在impossible级别添加令牌验证(tokenField())。
  • 动态内容渲染:{$html}显示对应级别文件处理后的内容,dvwaGuestbook()展示历史留言。

详细注释后的代码如下所示。

<?php
// 定义DVWA根目录的相对路径(向上两级)
define('DVWA_WEB_PAGE_TO_ROOT', '../../');// 引入DVWA核心页面初始化文件
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';// 启动DVWA页面,要求用户已认证并启用PHPIDS安全检测模块
dvwaPageStartup(array('authenticated', 'phpids'));// 创建新页面对象(初始化页面结构)
$page = dvwaPageNewGrab();// 设置页面标题(包含级别名称和默认分隔符)
$page['title'] = 'Vulnerability: Stored Cross Site Scripting (XSS)' . $page['title_separator'] . $page['title'];// 设置当前页面ID(用于标识)
$page['page_id'] = 'xss_s';// 设置帮助按钮和源码按钮的链接目标
$page['help_button'] = 'xss_s';
$page['source_button'] = 'xss_s';// 连接数据库
dvwaDatabaseConnect();// 检查是否点击了"Clear Guestbook"按钮(清空留言板)
if (array_key_exists("btnClear", $_POST)) {// 执行SQL清空guestbook表$query = "TRUNCATE guestbook;";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die('<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false) . '</pre>');
}// 根据Cookie中的安全等级加载对应的文件
$vulnerabilityFile = '';
switch($_COOKIE['security']) {case 'low':$vulnerabilityFile = 'low.php';    // 低防护break;case 'medium':$vulnerabilityFile = 'medium.php'; // 中防护break;case 'high':$vulnerabilityFile = 'high.php';   // 高防护break;default:$vulnerabilityFile = 'impossible.php'; // 最高防护break;
}// 引入对应安全等级的文件
require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/xss_s/source/{$vulnerabilityFile}";// 构建页面主体HTML
$page['body'] .= "
<div class=\"body_padded\"><h1>Vulnerability: Stored Cross Site Scripting (XSS)</h1><div class=\"vulnerable_code_area\"><form method=\"post\" name=\"guestform\"><table width=\"550\" border=\"0\" cellpadding=\"2\" cellspacing=\"1\"><tr><td width=\"100\">Name *</td><td><input name=\"txtName\" type=\"text\" size=\"30\" maxlength=\"10\"></td></tr><tr><td width=\"100\">Message *</td><td><textarea name=\"mtxMessage\" cols=\"50\" rows=\"3\" maxlength=\"50\"></textarea></td></tr><tr><td width=\"100\">&nbsp;</td><td><input name=\"btnSign\" type=\"submit\" value=\"Sign Guestbook\" onclick=\"return validateGuestbookForm(this.form);\" /><input name=\"btnClear\" type=\"submit\" value=\"Clear Guestbook\" onClick=\"return confirmClearGuestbook();\" /></td></tr></table>";// 如果是最高防护等级,添加CSRF令牌
if($vulnerabilityFile == 'impossible.php')$page['body'] .= tokenField();// 继续构建页面(包含动态生成的HTML内容和历史留言)
$page['body'] .= "</form>{$html}</div><br />" . dvwaGuestbook() . "<br /><h2>More Information</h2><ul><li>" . dvwaExternalLinkUrlGet('https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)') . "</li><li>" . dvwaExternalLinkUrlGet('https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet') . "</li><li>" . dvwaExternalLinkUrlGet('https://en.wikipedia.org/wiki/Cross-site_scripting') . "</li><li>" . dvwaExternalLinkUrlGet('http://www.cgisecurity.com/xss-faq.html') . "</li><li>" . dvwaExternalLinkUrlGet('http://www.scriptalert1.com/') . "</li></ul>
</div>";// 输出最终生成的HTML页面
dvwaHtmlEcho($page);
?>

2、Impossible.php

进入DVWA靶场源目录,找到Impossible.php源码,打开源码Impossible.php,如下所示。

Impossible这段代码实现了留言板的数据提交功能,包含多重安全防护:验证CSRF令牌防止伪造请求,通过trim()清理输入空格,使用stripslashes()处理魔术引号,mysqli_real_escape_string()防御SQL注入,htmlspecialchars()编码HTML特殊字符防止XSS攻击,最后通过PDO预处理语句安全写入数据库。每次请求后生成新CSRF令牌。具体如下所示。

  • CSRF防护:验证user_token与会话令牌匹配
  • 输入处理
    • trim():去除首尾空格
    • stripslashes():移除转义反斜杠
    • mysqli_real_escape_string():转义SQL特殊字符
    • htmlspecialchars():转义HTML标签(如<→&lt;)
  • 数据库操作:PDO预处理语句绑定参数,彻底杜绝SQL注入
  • 令牌更新:每次提交后生成新CSRF令牌

详细注释后的源码如下所示。

<?php
// 检查用户是否点击了提交按钮(btnSign)
if(isset($_POST['btnSign'])) {// 验证Anti-CSRF令牌,防止跨站请求伪造攻击checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php');// 获取用户输入的留言和姓名,并去除首尾空格$message = trim($_POST['mtxMessage']);$name = trim($_POST['txtName']);// 对留言内容进行安全处理:$message = stripslashes($message); // 去除反斜杠(防止魔术引号影响)// 转义特殊字符防止SQL注入(兼容性写法)$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call!", E_USER_ERROR)) ? "" : ""));$message = htmlspecialchars($message); // HTML实体编码防御XSS// 对姓名进行同样的安全处理:$name = stripslashes($name);$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call!", E_USER_ERROR)) ? "" : ""));$name = htmlspecialchars($name); // HTML实体编码// 使用预处理语句将数据安全插入数据库$data = $db->prepare('INSERT INTO guestbook (comment, name) VALUES (:message, :name);');$data->bindParam(':message', $message, PDO::PARAM_STR); // 绑定参数$data->bindParam(':name', $name, PDO::PARAM_STR);$data->execute(); // 执行SQL
}// 生成新的Anti-CSRF令牌供下次使用
generateSessionToken();
?>

3、htmlspecialchars功能函数

htmlspecialchars 是 PHP 中用于处理 HTML 特殊字符的重要函数,主要作用是将可能影响 HTML 解析的特殊字符转换为对应的 HTML 实体,从而防止跨站脚本(XSS)等注入攻击。默认情况下,htmlspecialchars() 处理以下关键字符。

原字符转换后的HTML实体转换目的
& (和号)&amp;防止混淆为实体的开始
" (双引号)&quot;防止跳出 HTML 属性(如 href="user_input"
' (单引号)&#039; (或 &apos;)防止跳出使用单引号的 HTML 属性(如 href='user_input'
< (小于号)&lt;防止新 HTML 标签的开始
> (大于号)&gt;防止新 HTML 标签的结束

htmlspecialchars函数定义如下所示。

htmlspecialchars(string $string,int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,?string $encoding = null,bool $double_encode = true
): string

其中flags的常用含义如下所示。

常量描述安全等级
ENT_COMPAT2仅转换双引号,不转换单引号中等
ENT_QUOTES3转换双引号和单引号高(推荐)
ENT_NOQUOTES0不转换任何引号低(不安全)

三、存储型XSS安全级别分析

四个安全级别(Low、Medium、High、Impossible)在存储型 XSS 防护上的区别如下所示。

级别XSS 防护措施CSRF 防护SQL 注入防护绕过难度
Low基础(mysqli_escape)极易
Medium部分过滤(script 标签)基础(mysqli_escape)较易
High增强 script 过滤(正则)基础(mysqli_escape)较难
Impossible全面转义(htmlspecialchars)有(Token)预处理语句(PDO)极难

1、Low 级别

  • 防护措施
    • 仅对输入的 message 和 name 进行了 SQL 注入防护mysqli_real_escape_string),用于防止数据库注入。
    • 未对 XSS 相关的恶意代码进行任何过滤或转义。
  • 风险点
    • 输入的内容会直接存储到数据库并原样输出到页面,可直接插入 <script> 等恶意脚本。
    • 示例 payload:<script>alert("XSS")</script> 可直接执行。
  • 安全性:无 XSS 防护,极易被利用。

2、Medium 级别

  • 防护措施
    • 对 message 字段:使用 strip_tags(移除 HTML 标签)+ htmlspecialchars(转义特殊字符),基本阻断 XSS。
    • 对 name 字段:仅简单替换 <script> 为空字符串(str_replace('<script>', '', $name)),且未转义其他特殊字符。
  • 风险点
    • name 字段的过滤不彻底,可通过大小写混淆(如 <sCriPt>)或拆分标签(如 <scr<script>ipt>)绕过。
    • 示例 payload:<sCriPt>alert("XSS")</sCriPt> 可执行。
  • 安全性:部分防护,但存在明显绕过手段。

3、High 级别

  • 防护措施
    • 对 message 字段的处理与 Medium 级别一致(strip_tags + htmlspecialchars),防护严格。
    • 对 name 字段:使用正则表达式 preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name),意图过滤任何包含 script 字符(无论大小写或中间插入其他字符)的标签。
  • 风险点
    • 正则仅针对 script 标签,可通过其他 HTML 事件或标签触发 XSS(如 <img src=x onerror=alert("XSS")>)。
    • 示例 payload:<img src=1 onerror=alert(1)> 可执行。
  • 安全性:增强了对 script 标签的过滤,但未覆盖所有 XSS 攻击向量。

4、Impossible 级别

  • 防护措施
    • 对 message 和 name 字段均进行 全面处理stripslashes(去除反斜杠)+ mysqli_real_escape_string(SQL 防护)+ htmlspecialchars(转义所有 HTML 特殊字符,如 <>& 等)。
    • 新增 CSRF 防护:通过 checkToken 验证请求中的 user_token 与会话中的 session_token,防止跨站请求伪造。
    • 使用 PDO 预处理语句 进行数据库操作,彻底避免 SQL 注入风险。
  • 风险点:无明显风险htmlspecialchars 会将所有 HTML 标签转义为实体(如 < 转为 &lt;),恶意脚本无法执行。
  • 安全性:防护措施完善,基本杜绝 XSS 和 SQL 注入风险。

四、Impossble防范分析

Impossible 级别通过多重机制实现了对存储型XSS 的彻底防御,核心措施包括htmlspecialchars编码处理和 Anti-CSRF 令牌验证。如下为impossible关卡的多种安全措施,不仅仅限于XSS的防御,还包括SQL注入防御等,具体如下所示。

1、防 CSRF 令牌验证

服务器通过generateSessionToken()生成唯一的session_token并存储在用户会话中,同时在表单中嵌入对应的user_token。当用户提交请求时,checkToken()函数验证请求中的user_token与会话中的session_token是否一致,确保请求来自当前用户的合法会话,防止攻击者伪造跨站请求提交恶意内容,从源头阻断 CSRF 攻击。

// 验证CSRF令牌
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// 生成CSRF令牌
generateSessionToken();

2、输入去斜杠处理

stripslashes()函数移除输入字符串中的反斜杠(\),避免因魔术引号(magic quotes)等机制自动添加的转义字符干扰后续的净化处理。例如,若输入为It\'s a test,处理后变为It's a test,确保后续的 SQL 转义和 HTML 实体化能准确作用于原始输入。

// 对message字段去斜杠
$message = stripslashes( $message );// 对name字段去斜杠
$name = stripslashes( $name );

3、SQL 注入防护

mysqli_real_escape_string()函数对 SQL 语句中的特殊字符(如单引号'、双引号"、反斜杠\等)进行转义,使其在 SQL 查询中被视为普通字符而非语法符号。例如,输入O'Neil会被转义为O\'Neil,防止攻击者通过输入注入恶意 SQL 代码,避免 SQL 注入安全风险。

// 对message字段进行SQL转义
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// 对name字段进行SQL转义
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

 4、数据库预处理语句

预处理语句将 SQL 命令结构与用户输入数据分离,通过bindParam()将用户输入绑定为查询参数(:message:name)。数据库会将参数视为纯数据而非可执行的 SQL 代码,即使输入中包含特殊字符,也不会被解析为 SQL 语法的一部分。这种方式彻底杜绝了通过字符串拼接导致的 SQL 注入风险,比单纯的字符转义更安全可靠。

// 使用PDO预处理语句插入数据
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();

5、htmlspecialchars防护

htmlspecialchars()函数将 HTML 中的特殊字符(如<>&"')转换为对应的 HTML 实体(如<转为&lt;>转为&gt;)。这使得浏览器会将这些字符解析为纯文本而非 HTML 标签或 JavaScript 代码,彻底阻断攻击者通过输入注入恶意脚本的可能,从根本上防御 XSS 攻击。。

// 对message字段进行HTML实体化
$message = htmlspecialchars( $message );// 对name字段进行HTML实体化
$name = htmlspecialchars( $name );


文章转载自:

http://Gl1PzdEp.ffrys.cn
http://F2Oe1h5R.ffrys.cn
http://XPH59nw9.ffrys.cn
http://j3HaySDj.ffrys.cn
http://JQSJBiIc.ffrys.cn
http://s8tOBqfE.ffrys.cn
http://96l5cJHB.ffrys.cn
http://dkFWBUrd.ffrys.cn
http://lOU4jKei.ffrys.cn
http://zr6e2Sto.ffrys.cn
http://RM8Eay7T.ffrys.cn
http://dgnmv2PS.ffrys.cn
http://CbEJ8pAB.ffrys.cn
http://BXuqADQY.ffrys.cn
http://LSQaQ7zx.ffrys.cn
http://1vamfpL8.ffrys.cn
http://SiKeKXnE.ffrys.cn
http://Jd3XGsUf.ffrys.cn
http://toz6tB4d.ffrys.cn
http://wKKmVeHk.ffrys.cn
http://Q4pgS7SH.ffrys.cn
http://fMxjWE5O.ffrys.cn
http://BESkGPuy.ffrys.cn
http://oDW5QunL.ffrys.cn
http://EMsicZNP.ffrys.cn
http://RObkpawQ.ffrys.cn
http://jg1BnYAO.ffrys.cn
http://byvBw21n.ffrys.cn
http://ZCudI7g2.ffrys.cn
http://5mOb6h2q.ffrys.cn
http://www.dtcms.com/a/364462.html

相关文章:

  • K8s Pod CrashLoopBackOff:从镜像构建到探针配置的排查过程
  • AI Agent重构SOC:下一代智能安全运营平台的能力跃迁
  • 解析SWOT分析和PV/UV这两个在产品与运营领域至关重要的知识点。
  • 【LeetCode 热题 100】72. 编辑距离——(解法一)记忆化搜索
  • 【LM358AD差分检测电压差】2022-11-30
  • 刻意练习理论
  • C++ 多线程编程
  • 【IO】进程间通信(IPC)练习
  • CAD/BIM软件产品技术深度分析文章写作计划
  • 7.4Element Plus 分页与表格组件
  • java spring cloud 企业工程管理系统源码+二次开发+定制化服务
  • 深兰科技AI问诊助手走访打浦桥街道社区卫生服务中心
  • Llama.cpp与CUDA Graph:深度学习推理框架的兼容性深度解析
  • Elasticsearch(text和keyword)区别分析
  • 怎么删除word空白页?【图文详解】删除最后一页空白页?5种删除word文档空白页方法?
  • Few-Shot Prompting 实战:用5个例子让GPT-4学会复杂任务
  • 线程与同步
  • 【Unity Shader学习笔记】(四)Shader编程
  • Java设计模式之结构型—适配器模式
  • SQLAlchemy ORM 入门教程
  • Low-Light Image Enhancement via Structure Modeling and Guidance 论文阅读
  • SQLint3 模块如何使用
  • Linux awk命令完全指南:从原理到实战,搞定文本处理难题
  • SQL(window)日志在linux 下查看
  • LangChain实战(十三):Agent Types详解与选择策略
  • 机器学习从入门到精通 - KNN与SVM实战指南:高维空间中的分类奥秘
  • Spring Boot 工程启动时自动执行任务方法
  • 图像正向扭曲反向扭曲
  • 安全测试漫谈:如何利用X-Forwarded-For头进行IP欺骗与防护
  • 停止所有dcoker容器