引言
一些网页当传入参数后,无论后端数据库是否执行成功,前端都返回一样的界面,这时无法通过简单的布尔盲注去判断是否语句执行成功,从而也无法盲注获取数据的每一位字符,这时就需要使用基于时间的盲注。
函数介绍
Mysql中有两个函数:
sleep()和benchmark(count,expr)。
01
sleep()
sleep函数接收一个参数,根据该参数会暂停语句执行一段时间,如:sleep(5)会使得sql语句暂停执行5秒钟,在navicat中执行“select sleep(5)”,会发现标题处一直在转圈,这就是暂停5秒的等待过程。

当执行完成后,我们也能看到结果处显示的执行时间,这多出的5秒就是暂停的时间。

因此我们可以利用mysql的这个特性进行时间盲注,而时间盲注往往与mysql的if语句搭配。
if(substr(database(),1,1))=’s’,1,sleep(5))
mysql的if(exp1, exp2, exp3),当exp1表达式的结果为true时,返回exp2的值,否则返回exp3的值。因此上述语句的含义为判断数据库名的第一位是否为s,若是,则返回1,否则执行sleep(5),暂停sql执行5秒钟,5秒执行完成后返回0。
利用类似这样的语句我们可以构造payload,通过页面的返回时间判断我们盲注的结果是否正确。
02
benchmark(count,exp)
该函数接收两个参数,第一个参数为次数,第二参数为表达式,含义为将表达式exp执行count个次数,因此通过反复执行增加sql查询的时间,该函数在payload中的利用与上述sleep()相同,只不过sleep通过指定的秒数拖长sql执行的时间,而benchmark(count,exp)通过反复执行的语句拖长时间。
如:benchmark(500000000,1=1)中将1=1这个表达式执行了500000000次,通过执行结果的时间统计,我们发现用了接近4秒的时间。

但是不建议使用benchmark函数,因为会占用cpu资源,在基于时间的盲注时,使用sleep()函数即可。
时间盲注
我们用sqli-labs的less-9举例,当我们输入正确的id=1时,发现页面返回了You are in,而我们输入错误的id=-1时,页面同样也返回了这个结果,因此此处无法使用简单的布尔盲注了。

我们采用基于时间的盲注,构造payload:
?id=1' and if(substr(database(),1,1)="a",sleep(5),1) --+
从a字符开始盲注,页面很快就返回了结果,说明数据库名第一位不是a,当盲注到s字符时,我们发现页面标题处一直在转圈。

5秒后,页面加载完成,因此说明数据库名第一位为s,紧接着修改substr函数的第二个参数值为2,盲注第二位字符,递归盲注的过程见下表:
substr表达式 | 盲注结果 |
substr(database(),1,1) | s |
substr(database(),2,1) | se |
substr(database(),3,1) | sec |
substr(database(),4,1) | secu |
substr(database(),5,1) | secur |
substr(database(),6,1) | securi |
substr(database(),7,1) | securit |
substr(database(),8,1) | security |
通过基于时间的盲注方式,最终我们得到了数据库名:security,利用这种方式可以获取其他数据。
小结
本节介绍了对于页面返回结果一直不变的情况下如何使用基于时间的盲注获取我们需要的数据,下一节将会介绍sql中文件上传注入的原理和方式,并使用python和php编写反向shell的监听端和连接端,深入理解getshell的逻辑过程。

感谢观看,理解有误之处,欢迎交流和指导!

刘杰寅
微信号|liujieyin666666
知乎|烈焰宝宝




