引言
Sql-1中介绍了sql注入的基本原理,从中我们可以发现有两个关键点:构造闭合区间和注入语句。在之前的例子中,参数username和password的闭合区间是用单引号构成的,如:
select * from users where username='Dumb' and password='Dumb'
构造闭合区间可以让sql语句正确且被执行,构造注入语句让我们实现注入的目的,显然构造正确的闭合区间是sql注入的基础,若无法找到正确的闭合区间,则无法进行下一步的注入工作。
闭合类型
1. 单引号闭合
SELECT * FROM tables WHERE id='1';
2. 双引号闭合
SELECT * FROM tables WHERE id="1";
3. 单引号加括号闭合
SELECT * FROM tables WHERE id=('1');
4. 双引号加括号闭合
SELECT * FROM tables WHERE id=("1");
5. 双括号闭合
SELECT * FROM tables WHERE id=(("1"));
注:双括号内的双引号可以更换为单引号,同时以此类推,只要是对称个数的括号,都可以作为合法的闭合区间。
6. 数字类型
SELECT * FROM tables WHERE id= 1;
判断闭合
下面来看less-3(less-3的实际闭合为(‘’)),首先盲猜是单引号闭合,构造payload为:
' or '1'='1
若less-3中确实为单引号闭合,则传递给mysql后完整的语句将会变成:
SELECT * FROM users WHERE id='' or '1'='1' LIMIT 0,1
其中or为或门的逻辑,即两边有一个为真则返回真,'1'='1'中字符串1恒等于字符串1,因此表达式id='' or '1'='1'中所有参数的闭合方式均对称,因此sql语句正确,返回值应为1,则mysql会查询第一条记录并返回,正常情况下,我们应该可以看到Dumb的记录(Dumb为users表中第一条记录)。
但less-3的实际闭合为(''),因此完整的语句将会变成:
SELECT * FROM users WHERE id=('' or '1'='1' ) LIMIT 0,1
从常理来说,or左边的表达式(''闭合不对称,or右边的表达式中等号右侧的'1')也闭合不对称,那么sql语句拼接后肯定会有语法错误,因此页面返回错误,所以我们可以通过构造payload: 'or '1'='1 观察页面返回情况来判断闭合区间。但往往事实与我们想象的不一样,使用该payload对less-3进行测试,发现登录成功,页面正确返回了Dumb的登录信息,如下图所示(浏览器将’转义为%27,将空格转义为%20)。

难道这样就可以证明less-3中的闭合区间是单引号吗?事实显然不是,那么这其中到底发生了什么?这就涉及到mysql的非贪婪和对称策略。
非贪婪和对称策略
首先声明:mysql的非贪婪和对称策略官方并不一定有此相关的定义,只是我个人根据平时碰到的问题所形成的理解。
首先让我们看个实例,现在已经知道users表中不存在id为‘1qwe’的用户,因此查询‘1qwe’结果应该为空,但实际上查询了“Dumb”的信息,如下图所示。

这种现象我称之为mysql的非贪婪属性,当执行查询语句时,id接受的参数为1qwe,mysql会从左往右查找,只要找到数据库中存在的记录就返回,无需全部符合,即开头为1,后面无论是什么字符,都会返回Dumb的记录。
其次来看对称策略,上述说到('' or '1'='1')这个payload的例子,mysql的语法会遵循对称策略,只要整个的区间是闭合的,那么语法就是正确的。该payload可以这样理解:闭合区间为(),参数为'' or '1'='1'表达式的值,该表达式的值为1,因此完整的查询语句等同于:
SELECT * FROM users WHERE id=(1) LIMIT 0,1
这也就是为什么less-3依旧返回Dumb记录的原因了,因此对于没有报错提示的情况,只能对于每一种闭合区间进行尝试,直到返回预期的结果;而对于有报错信息的情况可以根据报错信息判读闭合区间,如下图所示:

在less-3的参数部分输入1',发现出现错误,根据错误信息得知闭合区间为('')。对于数字类型,也是一样的思路,只不过整型没有标示符来标志闭合区间,只是单个的数字参数。
小结
本节介绍了mysql的一些基本特性以及闭合区间的分类和重要性,同时需要强调的是:构造闭合区间是sql注入的基本,构造闭合区间可以让sql语句正确且被执行,构造注入语句让我们实现注入的目的。下一节将会具体介绍报错注入中floor的详细原理和extractvalue的使用。

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

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




