Mysql 字符串与0比较为Ture 延伸到SQL注入的有趣问题

目录

初探

真相渐现

延伸到SQL注入

字符串列数据提取

判断列名是否存在

新型万能密码


 

初探

有一天突然发现Mysql中一个有趣的现象:

百思不得其解,想着是不是由于mysql的字符串转化数字的原因,于是试验了一下:

扫描二维码关注公众号,回复: 11648424 查看本文章

自动将字符串类型的"123"转为数字型的123,然后与1相加。

下面试验了数字与字符串掺杂的情况:

直接将首位的1给转化了,其余的字符串则忽略掉。

但若不是以字符串为开头则会失败,字符串"te1st2"、"test"转化数字失败则会返回0,与1相加刚好为1:

真相渐现

通过上述试验得出结论:

当字符串与数字比较、相加时,字符串会自动转化为数字。

若字符串以数字开头,则会转化为该开头的数字;否则会转化失败,返回0

于是由下表简单地呈现:

原始语句 过程释义 结果 备注
select "test" = 1; select 0 = 1; 0 (False) "test"转化失败,返回0
select "test" = 0; select 0 = 0; 1 (True) "test"转化失败返回0,与0比较相等

值得一提的是,

  • 当等号两边都为字符串的时候,字符串不会转化为数字:

但是可以通过+0来强制转化类型:

  • 当在字符串与数字使用like进行比较时,若字符串不是纯数字,则不会进行转化

纯数字就可以:

但可以使用%通配符:

延伸到SQL注入

通过上述的 select "test" = 0; 为True的原理,可以引申到SQL注入中。

字符串列数据提取

前提条件是字段值要类似于"test"的字符串类型才可以:

当waf拦截等号(=)时,也可以用 like 关键字进行绕过:

like的优先级大于=,上述语句等价于:

select * from users where username = (1 like "2");

判断列名是否存在

简单的,我们知道 "" like "123" 为0:

同样可以以永真的条件列出所有数据:

当"123"用某个列的值来替代的时候,就可以判断某个列是否存在:

若列名存在,还可以通过赋值来排查某一行数据:

新型万能密码

由于登录处的username为字符串类型,且 "xxx" like 1 为 0,所以构造之后就相当于: "xxx" = 0  ==> Ture

原始语句 过程释义 结果 备注
select * from users where username = "xxx" like 1;

1. select * from users where username = 0;

2. select * from users where True;

1 (True)

1. "xxx" like 1 返回 0

2. "xxx"转化失败返回0,与上一步的0比较相等返回1(Ture)

不需要知道真实用户名,直接以True永真条件登录:

xxx' like 1 #

当拦截关键字like时,可以直接用跳过like来注入:

'+0 #

原始语句 过程释义 结果 备注
select * from users where username = "xxx" + 0;

1. select * from users where username = 0;

2. select * from users where True;

1 (True)

1. "xxx"+0, "xxx"转化失败返回0

2. 与上一步的0比较相等返回1

参考: http://www.6tie.net/p/1167757.html

猜你喜欢

转载自blog.csdn.net/angry_program/article/details/108032253