1. Sql注入是什么?
不知道有没有测试同仁遇到过类似这样的情景:登录或者查询数据失败的时候,程序给出了一个包含SQL脚本的提示框。作为测试人员,我们隐约感觉这样的提示信息不友好,于是要求开发人员修改,开发人员却告诉我们这些信息是数据库返回的错误,而且某某原因(比如使用了第三方的开发框架)改不了?
有没有测试同学想过,上例中的sql脚本里,包含了可以被黑客利用的信息?
诸位看官别急,且听小编下文分解。
要解答这个问题,就得从本文的话题——sql注入说起。
所谓SQL注入,简单理解就是在页面上的输入框中输入恶意的sql命令,伴随着请求的提交来欺骗服务器能执行。比如先前的某影视网站泄露VIP会员密码就是因为存在sql注入漏洞导致的。
我们来看一个例子:
假设这个路由登录页面,是通过拼接字符串的方式构造动态sql语句,然后到数据库中校验用户名密码是否存在网站老说提交内容有非法字符,假设其后台sql语句是:
sql='select * from users where user='&user&' and passwd='&passwd&'
复制
那么我们使用admin做用户名,用'1’ or 'a'='a来做密码的话,那么查询就变成了
select * from users where user= ‘admin’ and passwd='1‘ or 'a'='a'
复制
这样的话,根据运算规则(先算and 再算or),最终结果为真,这样就可以进到后台了。
注意:
这个漏洞存在必须要有3个条件:
从上面这个例子中,可以看出来sql注入的原理就是通过构建特殊的输入参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,因程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
这种因程序员对输入未进行细致地过滤,从而执行了非法的数据查询的攻击叫做代码层注入。还有一种sql注入类型叫做平台层注入,是由不安全的数据库配置或数据库平台的漏洞所致。
2. Sql注入的危害?
3. Sql注入的危害?
sql注入时,有时候需要猜测数据库的table名称,我们用下面这个例子来演示一下:
1、打开靶机,大家可以看到这是一个根据用户ID查询用户信息的页面:
2、在“User ID: ”输入框里输入“3”,提交,可以看到页面显示ID = 3的用户信息,通过页面返回,我们猜测程序伪代码是:select first_name,last_name from TABLENAME where user_id = '+文本框内容+';
3、模拟黑客“拖库”,在“User ID: ”输入框里输入“' or 1=1 -- ”,这里的"--"是MYSQL数据库的注释符,在它后面的内容全部作为注释信息,不被执行。提交后,程序拼接并在数据库执行的SQL是:select first_name,last_name from TABLENAME where user_id ='' or 1=1(因为--的存在,程序代码里主动拼接出的'符号,变成了注释内容,躲避了语法错误), 攻击成功,因为“or 1=1”的存在,返回表中所有用户信息(可以和数据库客户端截图对比观察):
4、猜表名,在“User ID: ”输入框里输入“' 3' and exists(select * from admin) --”,提交,系统返回dvwa.admin表不存在(类似的,我们可以根据数据库返回,判断数据库的具体类型):
5、继续猜表名,在“User ID: ”输入框里输入“' 3' and exists(select * from users) --”,提交,系统返回id =3的数据,证明数据表dvwa.users存在:
扩展:
猜表名的语法
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 这样是不行的。
很多人都是喜欢查询里面的内容,一旦iis没有关闭错误提示的,那么就可以利用报错方法轻松获得库里面的内容。
获得数据库连接用户名:
and user>0
这里引用《SQL注入天书》里面的一段话来讲解:
"重点在and user>0,我们知道,user是SQLServer的一个内置变量,它的值是当前连接的用户名,类型为nvarchar。拿一个 nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQLServer的出错提示是:将nvarchar转换int异常,XXXX不能转换成int"
看到这里大家明白了吧,报错的原理就是利用SQLserver内置的系统表进行转换查询,转换过程会出错,然后就会显示出在网页上,另外还有类似的 and 1=(selet top 1 user from admin),这种语句也是可以爆出来的。and db_name()>0 则是暴数据库名。
4. 怎么防止这种攻击呢?
在以前,很多程序员习惯用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式。如今参数化查询已经成了普遍做法,加上都校验输入也成了一种共识,所以存在SQL 注入漏洞的网站已经越来越少,但仍不可忽视。根据数据统计,在OWASP Top 10(2017 RC2)中,注入类攻击名列榜首。
归纳一下,主要有以下几点:
1.校验输入。
检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和服务器端都执行之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双"-"进行转换等。
2.使用参数化的过滤性语句
永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.密码等敏感信息加密
加密用户输入的数据,然后再将它与数据库中保存的数据比较,这相当于对用户输入的数据进行了“消毒”处理,用户输入的数据不再对数据库有任何特殊的意义,从而也就防止了攻击者注入SQL命令
4.存储过程来执行所有的查询
SQL参数的传递方式将防止攻击者利用单引号和连字符实施攻击。此外,它还使得数据库权限可以限制到只允许特定的存储过程执行网站老说提交内容有非法字符,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。
5.应用的异常信息应该给出尽可能少的提示
最好使用自定义的错误信息对原始错误信息进行包装。避免出现一些详细的错误消息(数据库的类型、结构等信息),因为黑客们可以利用这些消息为其他类型的攻击做准备,可谓是攻击的一个预备步骤。
6.确保数据库安全
锁定你的数据库的安全,只给访问数据库的web应用功能所需的最低的权限,撤销不必要的公共许可,使用强大的加密技术来保护敏感数据并维护审查跟踪。如果web应用不需要访问某些表,那么确认它没有访问这些表的权限。如果web应用只需要只读的权限,那么就禁止它对此表的 drop 、insert、update、delete 的权限,并确保数据库打了最新补丁。
7.sql注入的检测
一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。
8.安全审评
在部署应用系统前,始终要做安全审评。建立一个正式的安全过程,并且每次做更新时,要对所有的编码做审评。开发队伍在正式上线前会做很详细的安全审评,然后在几周或几个月之后他们做一些很小的更新时,他们会跳过安全审评这关, “就是一个小小的更新,我们以后再做编码审评好了”。