挖洞经验 | 构造基于时间的盲注漏洞(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 排除的注入类型

  1. UNION-Based注入:不可行,因为查询语句结构为ORDER BY类型
  2. 报错型注入:总是返回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. 漏洞利用流程总结

  1. 参数识别:寻找可能影响SQL查询的参数(如order, sort等)
  2. 初步测试:使用单引号等简单Payload确认漏洞
  3. 注入类型判断
    • 尝试UNION注入
    • 尝试报错注入
    • 最后尝试时间盲注
  4. 绕过限制
    • 当标准Payload失败时,尝试版本探测
    • 根据数据库版本定制Payload
  5. 有效Payload构造
    • 使用嵌套子查询结构
    • 避免直接调用可能被禁用的函数

6. 防御建议

  1. 参数化查询:使用预处理语句
  2. 输入验证
    • 限制order by参数为预定义值
    • 过滤特殊字符
  3. 最小权限原则:数据库账户使用最低必要权限
  4. 错误处理:避免返回详细错误信息
  5. WAF配置:部署并正确配置Web应用防火墙

7. 实际应用价值

  • 该漏洞获得了$3500的漏洞奖励
  • 展示了即使看似安全的系统也可能存在高级注入漏洞
  • 强调了全面测试和多种技术尝试的重要性
基于时间的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的漏洞奖励 展示了即使看似安全的系统也可能存在高级注入漏洞 强调了全面测试和多种技术尝试的重要性