网络安全之SQL注入

SQL注入的定义

SQL注入是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击。

当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击。
如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生sql注入。

我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。

理解:
现代的注入手法,其实就是利用现成的表格数据来执行非常规指令。简单的说,利用非该段执行文本数据,代替正常数据做运算从而得到正确解。能够实现这种操作的技术就叫做sql注入。

SQL注入为什么会成功?

Sql注入攻击是利用是指利用设计上的漏洞,在目标服务器上运行Sql语句以及进行其他方式的攻击,动态生成Sql语句时没有对用户输入的数据进行验证是Sql注入攻击得逞的主要原因。

为什么发生SQL注入?

程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患
用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据或进行数据库操作

当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击。如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生sql注入。

sql注入可能导致攻击者使用应用程序登陆在数据库中执行命令。
如果应用程序使用特权过高的帐户连接到数据库,这种问题会变得很严重。在某些表单中,用户输入的内容直接用来构造(或者影响)动态sql命令,或者作为存储过程的输入参数,这些表单特别容易受到sql注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段数据库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是sql注入就发生了。

SQL注入的分析

对于Java数据库连接JDBC而言,SQL注入攻击只对Statement有效,对PreparedStatement是无效的,这是因为PreparedStatement不允许在不同的插入时间改变查询的逻辑结构。
如验证用户是否存在的SQL语句为:用户名'and password='密码'

如果在用户名字段中输入: 'or 1=1'或是在密码字段中输入:'or 1=1'
将绕过验证,但这种手段只对只对Statement有效,对PreparedStatement无效。相对Statement有以下优点:

1.防注入攻击
2.多次运行速度快
3.防止数据库缓冲区溢出
4.代码的可读性可维护性好
这四点使得PreparedStatement成为访问数据库的语句对象的首选,缺点是灵活性不够好,有些场合还是必须使用Statement。

SQL的注入流程

判断SQL注入点

找注入点是最关键,也最基础的一个环节
本质原理:
找一个需要后台处理后提交给数据的点,所有的输入只要和数据库进行交互的,都有可能触发SQL注入
一般分为三大类:
Get参数触发SQL注入
POST参数触发SQL注入
Cookie触发SQL注入

例如:
在常规的链接的参数中(链接?参数)找形如?id=num的搜索框
而验证是否存在注入点方法有很多种
最常规也是最简单的方法,引入单引号判断是否注入点

http://host/test.php?id=100;返回错误说明有可能注入
http://host/test.php?id=100 and 1=1 返回正常
http://host/test.php?id=100 and 1=2 返回错误

判断注入类型

数字型注入点

http://host/test.php?id=100 and 1=1

SELECT first_name, last_name FROM users WHERE user_id = '1' or '1'='1'

字符型注入点

http://host/test.php?name=man' and '1'='1 

select * from student where  sname='张三'  or 1=1 --  and password='123'
"select id from users where username = ''+username +"'"  and password = ''  + password +"'" 

在表单中username的输入框中输入’ or 1=1-- ,password的表单中随便输入一些东西,假如这里输入123.此时我们所要执行的sql语句就变成了select id from users where username = ’ ’ or 1=1-- and password = ‘123’,我们来看一下这个sql,因为1=1是true,后面 and password = '123’被注释掉了。

搜索型注入点 — 目前常见的

http://host//test.php?keyword=python%' and 1=1 and '%'='

内联式SQL注入 –常用
在 SQL语句中, AND的优先级是大于 OR的
先计算 AND,然后计算 OR,所以这里我们的语句会被 OR分为两段 SQL语句

SELECT * FROM admin WHER username=''

or

''='' AND password ='fuzz'

SELECT * FROM admin WHER username='fuzz' AND password =''

or

''=''


SELECT * FROM admin WHER username='fuzz' AND password =''

or

''=''

这里我们第一句是返回失败的,但是我们的第二句''=''是返回成功的,OR逻辑是有一个是成功就返回成功,于是我们的整个语句就会返回成功

SQL注入的通常方法

SQL注入主要分两种方式:

一是直接将代码插入到与SQL命令串联在一起并使得其以执行的用户输入变量。上面笔者举的例子就是采用了这种方法。由于其直接与SQL语句捆绑,故也被称为直接注入式攻击法。

二是一种间接的攻击方法,它将恶意代码注入要在表中存储或者作为原书据存储的字符串。在存储的字符串中会连接到一个动态的SQL命令中,以执行一些恶意的SQL代码。注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。如以直接注入式攻击为例。就是在用户输入变量的时候,先用一个分号结束当前的语句。然后再插入一个恶意SQL语句即可。由于插入的命令可能在执行前追加其他字符串,因此攻击者常常用注释标记“—”来终止注入的字符串。执行时,系统会认为此后语句位注释,故后续的文本将被忽略,不背编译与执行。

注入大致方法:  
  先猜表名 And (Select count(*) from 表名)<>0
  猜列名 And (Select count(列名) from 表名)<>0
  或者也可以这样

and exists (select * from 表名)
and exists (select 列名 from 表名)

返回正确的,那么写的表名或列名就是正确
这里要注意的是,exists这个不能应用于猜内容上,例如and exists (select len(user) from admin)>3这样是不行的

防止SQL注入

防止SQL注入,我们需要注意以下几个要点:

1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。

数据库操作,是触发技术使用的关键。
围绕这一点,可以想到许多系统层面的防护。
第一点就是,避免使用普适性的名词去做主要关键词,可以做适当的修改变形。sql注入其实也是技术门槛比较高的,它需要破解者对于项目网站本身就有一定的了解。
第二点可以考虑加强过滤手段,通过对于主要关键词周边风险词的限制降低风险。根据理论模型来看,这种语句过滤可以极大程度防范技术侵入。

更多相关一
更多相关二

猜你喜欢

转载自blog.csdn.net/qq_43573663/article/details/111084514