MySQL False注入及技巧总结

MySQL False注入及技巧总结

作者:Leej

预估稿费:300RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

0x01 False Injection


引子

首先我们常见的注入

MySQL False注入及技巧总结

这些都是基于1=1这样的值得比较的普通注入,下面来说说关于False注入,利用False我们可以绕过一些特定的WAF以及一些未来不确定的因素,其中有些姿势之前了解但是没有去深入,这次做一个归纳总结。

首先抛出这么一个问题

MySQL False注入及技巧总结

为什么username=0会导致返回数据呢?

这就是一个基于false注入的例子,下面在举一个例子

MySQL False注入及技巧总结

和上面是同一个表,但是为什么这里只返回了两组数据呢?说到这里不得不说一说有关于MYSQL的隐式类型转换。

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 转换为浮点数进行比较

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

最后那一句话很重要,说明如果我是字符串和数字比较,需要将字符串转为浮点数,这很明显会转换失败

在这里我试了试如果是字符串和数字比较:

MySQL False注入及技巧总结

可以看到在进行类型转换的时候,将字符串转换的时候会产生一个warning,转换的结果为0,但是如果字符串开头是数字的时候还是会从数字部分截断,转换为数字。

现在可以很好理解开头说的为什么username=0会导致返回数据了,就是因为这里会将数据转换为浮点数比较,但是字符串转换会出问题,从而返回0使得0=0从而为true得到结果,而后面passwd查询少一组数据的原因就是admin的passwd字段第一个字符是2 从而返回2 并非为0。

2、利用

实际中我们接触到的语句都是带有引号的,类似于where username='+input+' 这样的,这时候我们就需要做一些处理来构造false注入的利用点。

MySQL False注入及技巧总结

MySQL False注入及技巧总结

MySQL False注入及技巧总结

这里官方给出的就是利用异或,其实这里并不需要’admin‘只要是一串字符串就可以

MySQL False注入及技巧总结

异或会使字符串都转为浮点型,都变为了0,由于0=0^0 -> 1^0 -> 1当然对于这个题并不一定利用这个,直接截取字符串作比较就可以,但是这里只是提供一种姿势,由于mysql的灵活,其花样也比较多还有就是构造的payload比较简短,例如'+'、'^'、'/4#这样只有三个字符便可以绕过登录,简单粗暴,还有就是类似的文章不多,许多开发人员容易忽视这些细节。

3.1、结合盲注

上面的例子payload就是利用字符串类型转换导致false注入结合盲注的一个过程

0x02 一些注入的技巧


mysql中,我们用得到的:

常量:true, false, null, N, current_timestamp变量:@myvar:=1

系统变量:@@version, @@datadir....

常用函数:version(), pi(), pow(), char(), substring()

字符串生成:hex(), conv()

有关于字符串生成的一些基础字符:true=1,floor(pi())=3,ceil(pi())=4,floor(version())=5,ceil(version())=6

MySQL False注入及技巧总结

MySQL False注入及技巧总结

这里是可以注入绕过的,在php关于MD5函数的介绍说

如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。

也就是找到一个字符串MD5的二进制恰好和字符编码中的某些编码对上了,就可以产生注入,原文作者找到这么一串字符串ffifdyop,md5加密后对应字符编码刚好是'or'<trash>,便产生注入

这里的原文在这

END


false注入也许在某些时候会利用,但是对其中并不是很了解,所以在这里进行了一下系统地总结。

同时往往在利用的时候往往不只是一个点,要结合许多姿势。文章后半部分就是总结了一些注入小姿势,并不是很系统有些散,如果有错误欢迎大佬指出。

参考


https://www.exploit-db.com/papers/18263/

https://www.secpulse.com/archives/57197.html

http://cvk.posthaven.com/sql-injection-with-raw-md5-hashes

https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: