
1. 什么是sqli-labs靶场sqli-labs是一个专门用于学习和实践SQL注入技术的开源靶场项目。它由印度安全研究员Audi-1开发并维护目前托管在GitHub上。这个靶场包含了从基础到高级的各种SQL注入场景是Web安全领域最经典的实训平台之一。我第一次接触sqli-labs是在2018年的一次CTF比赛后。当时遇到一个复杂的SQL注入题完全无从下手赛后前辈就推荐我用这个靶场系统性地练习。经过两个月的实战我不仅拿下了那类题型还发现了许多常规渗透测试中的注入漏洞。2. 环境搭建与配置2.1 基础环境准备要运行sqli-labs你需要准备以下环境PHP 5.4/7.xMySQL 5.xApache/Nginx服务器推荐使用XAMPP或Docker一键部署。以XAMPP为例下载最新版XAMPP含ApacheMySQLPHP将sqli-labs解压到htdocs目录访问http://localhost/sqli-labs进行初始化注意PHP7以上版本需修改sqli-labs/sql-connections/db-creds.inc中的mysql_connect为mysqli_connect否则会报函数废弃错误。2.2 数据库配置技巧初始化时会自动创建数据库但经常遇到的两个问题MySQL 8.0的密码认证插件冲突需执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码表创建失败手动导入sqli-labs/sql-lab.sql文件建议专门创建一个低权限用户用于练习CREATE USER sqlilocalhost IDENTIFIED BY password; GRANT SELECT ON security.* TO sqlilocalhost;3. 关卡设计与解题思路3.1 基础注入关卡Lessons 1-20这部分的关卡主要覆盖基于错误的注入Error-based联合查询注入Union-based布尔盲注Boolean Blind时间盲注Time-based以最基础的Lesson 1为例测试单引号触发错误id1确定列数order by 4报错而order by 3正常联合查询获取数据union select 1,2,33.2 进阶挑战关卡Lessons 21-65从这里开始引入更复杂的场景Cookie/Header注入二次注入Second Order过滤绕过WAF Bypass堆叠查询Stacked QueriesLesson 38是典型的二次注入案例注册用户时插入恶意payloadadmin--修改密码时触发UPDATE users SET passwordnewpass WHERE usernameadmin-- 4. 自动化工具实战4.1 使用SQLmap通关虽然手动注入是基础但实际渗透中常使用自动化工具。以Lesson 1为例sqlmap -u http://localhost/sqli-labs/Less-1/?id1 --batch --dbs关键参数说明--risk3启用危险等级更高的测试--level5增加测试的详尽程度--tamperspace2comment使用空格替换绕过WAF4.2 自定义Tamper脚本针对特定过滤规则可以编写tamper脚本。例如遇到关键词过滤def tamper(payload): return payload.replace(SELECT, SELSELECTECT) if payload else payload保存为bypass.py后使用--tamperbypass5. 防御方案与实战技巧5.1 安全编码实践从开发角度预防SQL注入使用预处理语句PDO/mysqli最小权限原则配置数据库账户输入验证白名单而非黑名单PHP示例$stmt $conn-prepare(SELECT * FROM users WHERE id ?); $stmt-bind_param(i, $id);5.2 靶场练习的进阶方法我总结的高效练习路径先手动完成所有基础关卡用Burp Suite记录流量分析注入点尝试用不同编码方式绕过Hex/Base64等修改源码增加过滤规则自我挑战一个实用的调试技巧在sqli-labs的index.php中添加error_reporting(E_ALL)可以显示完整错误信息帮助理解后台逻辑。6. 常见问题排查6.1 页面空白或500错误可能原因及解决方案PHP版本兼容性问题 → 降级到PHP 5.6或修改代码MySQL连接失败 → 检查db-creds.inc中的凭据文件权限不足 →chmod -R 755 sqli-labs6.2 关卡无法完成典型情况Lesson 13的报错注入需要?id1)而非单引号Lesson 24的二次注入必须完成完整注册流程Lesson 54-65需要先解密挑战码建议开启MySQL的general log查看实际执行的SQL语句SET global general_log 1; SET global log_output table;