基于时间的盲注SQL注入漏洞与防护
字数 1142 2025-11-22 08:09:20
基于时间的盲注SQL注入漏洞与防护
描述
基于时间的盲注(Time-Based Blind SQL Injection)是SQL注入的高级形式,当应用对数据库查询结果无直接回显(如错误信息或数据展示)时,攻击者通过构造特定负载,根据数据库响应延迟判断查询真假,从而逐字符提取数据。这种攻击隐蔽性强,常用于严格过滤或错误处理机制完善的应用。
解题过程
-
漏洞原理分析
- 应用未对用户输入充分过滤,直接将输入拼接至SQL查询中。
- 数据库支持时间延迟函数(如MySQL的
SLEEP()、PostgreSQL的PG_SLEEP())。 - 攻击者通过注入条件语句(如
IF(condition, SLEEP(5), 0)),观察响应延迟验证条件真假,逐步推断数据内容。
-
攻击步骤分解
步骤1:确认注入点- 测试输入点(如URL参数、表单字段)是否触发延迟。例如,提交
id=1' AND SLEEP(5)--,若响应延迟5秒,则存在时间盲注漏洞。 - 注意:需区分网络延迟与数据库延迟,多次测试确保准确性。
步骤2:判断数据库类型
- 不同数据库的延迟函数语法不同:
- MySQL:
SLEEP(5)或BENCHMARK(1000000, MD5('test')) - PostgreSQL:
PG_SLEEP(5) - Oracle:
DBMS_LOCK.SLEEP(5)
- MySQL:
- 通过尝试特定函数确定数据库,例如提交
id=1' AND PG_SLEEP(5)--,若延迟则目标为PostgreSQL。
步骤3:逐字符提取数据
- 以获取数据库名为例,使用条件延迟判断字符的ASCII码:
- 负载示例:
id=1' AND IF(ASCII(SUBSTRING(database(),1,1))>100, SLEEP(5), 0)-- - 若延迟5秒,说明数据库名第一个字符的ASCII码大于100;否则小于等于100。
- 通过二分法(如比较>50、>75等)逐步缩小范围,最终确定字符的ASCII值,转换为字符。
- 负载示例:
- 重复此过程,依次获取后续字符,直至完成数据库名、表名、字段名及具体数据的提取。
- 测试输入点(如URL参数、表单字段)是否触发延迟。例如,提交
-
防护方案
- 参数化查询(首选):使用预编译语句分离查询结构与数据,避免拼接。例如在Java中:
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE id = ?"); stmt.setInt(1, userId); // 参数自动转义,防止注入 - 输入验证:严格限制输入格式(如数字类型校验、长度限制),拒绝非法字符。
- 最小权限原则:数据库账户仅授予必要权限,避免使用高权限账户连接。
- WAF(Web应用防火墙):配置规则检测异常延迟请求,拦截可疑负载。
- 日志监控:记录长时间运行的查询,及时告警异常模式。
- 参数化查询(首选):使用预编译语句分离查询结构与数据,避免拼接。例如在Java中:
总结
时间盲注通过延迟响应间接提取数据,防护需结合代码层安全开发(如参数化查询)与运维层监控(如WAF)。定期渗透测试可验证防护措施有效性。