挖洞经验 | 构造基于时间的盲注漏洞(Time-Based SQLi)
字数 1416 2025-08-15 21:33:12
基于时间的SQL盲注漏洞(Time-Based SQLi)构造与利用
1. 漏洞发现过程
1.1 初始发现
- 发现一个子域名网站,具有登录和注册功能
- 网站包含搜索功能,初步XSS测试无效
- 点击引用标题(如引用ID、类型)时,URL跳转为:
?order=type&ordering=ASC&search= - 观察到
ASC参数,推测后台SQL查询可能为:SELECT * FROM referrals ORDER BY type ASC
1.2 初步测试
- 使用单引号测试:将
order=type改为order=type' - 服务端返回500错误,确认存在SQL注入可能性
- 尝试基于UNION的SQL注入失败,只能实现
order by 18查询
2. 注入类型分析
2.1 排除的注入类型
- UNION-Based注入:不可行,因为查询语句结构为
ORDER BY类型 - 报错型注入:总是返回500状态空白页面,无额外信息
2.2 确认Time-Based盲注
- 尝试标准时间延迟Payload均失败:
sleep(10)--benchmark(1000000000,md5(1))--pg_sleep(10)--WAITFOR DELAY '00:00:10';--
- 推测可能原因:
- WAF拦截
- 数据库禁用时间延迟函数
3. 绕过技术
3.1 Boolean-Based盲注尝试
- 使用Payload:
if(1=1,1,(select 1 union select 2)) - 预期行为:
1=1时返回200状态1>2时返回500状态
- 结果:比较运算符(=, <, >)被拦截
3.2 数据库版本探测
- 使用MySQL版本注释语法:
/*!50000 someInvalidSQLSyntax*/ - 原理:
- 版本≥5.00.00时执行Payload
- 版本<5.00.00时忽略
- 使用Burp Intruder枚举版本:
/*!50731someInvalidSQLSyntax*/→ 500错误/*!50732someInvalidSQLSyntax*/→ 200成功
- 结论:MySQL 5.7.31
4. 有效Payload构造
4.1 成功的时间延迟Payload
(select*from(select(sleep(10)))a)- 验证:
- 修改为
sleep(30)也成功执行
- 修改为
- 特点:
- 嵌套子查询结构
- 避免直接使用
sleep()函数
5. 漏洞利用流程总结
- 参数识别:寻找可能影响SQL查询的参数(如order, sort等)
- 初步测试:使用单引号等简单Payload确认漏洞
- 注入类型判断:
- 尝试UNION注入
- 尝试报错注入
- 最后尝试时间盲注
- 绕过限制:
- 当标准Payload失败时,尝试版本探测
- 根据数据库版本定制Payload
- 有效Payload构造:
- 使用嵌套子查询结构
- 避免直接调用可能被禁用的函数
6. 防御建议
- 参数化查询:使用预处理语句
- 输入验证:
- 限制order by参数为预定义值
- 过滤特殊字符
- 最小权限原则:数据库账户使用最低必要权限
- 错误处理:避免返回详细错误信息
- WAF配置:部署并正确配置Web应用防火墙
7. 实际应用价值
- 该漏洞获得了$3500的漏洞奖励
- 展示了即使看似安全的系统也可能存在高级注入漏洞
- 强调了全面测试和多种技术尝试的重要性