Fork me on GitHub

SQL Injection的深入探讨

SQL injection可以说是一种漏洞,也可以说成是一种攻击方法,程序中的变量处理不当,对用户提交的数据过滤不足,都可能产生这个漏洞,而攻击原理就是利用用户提交或可修改的数据,把想要的SQL语句插入到系统实际SQL语句中,轻则获得敏感的信息,重则控制服务器。SQL injection并不紧紧局限在Mssql数据库中,Access、Mysql、Oracle、Sybase都可以进行SQL injection攻击。

一、SQL Injection的原理
    SQL Injection的实现方法和破坏作用有很多,但万变不离其宗,其原理可以概括为一句话 :SQL Injection就是向服务器端提交事先准备好的数据,拼凑出攻击者想要的SQL语句,以改变数据库操作执行计划。这句话主要包含这么三层意思:

  1. 攻击者通过何种途径注入?
        存在SQL Injection漏洞的地方都是应用程序需要根据客户端环境构造SQL语句的地方。由此可以推论,只要存在"客户端数据替换预定义变量"的地方,就有可能被注入。 客户端提交数据可以有很多种方式:GET,POST,Client-Agent,Cookie,Server Enviroment...
  2. 攻击者为什么可以将它想要的语句"注入"?
    因为服务器端应用程序采用拼凑SQL语句的方式,这使得攻击者有机会在提交的数据中包含SQL关键字或者运算符,来构造他们想要的语句。
  3. SQL Injection最终结果是什么?
    改变数据库操作执行计划。这个结果不一定是恶意的,只要你的SQL语句没有按照你预期的计划(plan)执行,那么就可以视为被注入了,不管提交数据的人是不是恶意的。

注:这里只是简单的列出SQL 注入的方式,展开来说明可参看SQL Injection的源由與防範之道駭客的 SQL填空遊戲(上)駭客的 SQL填空遊戲(下)

二、ASP.NET应用程序如何避免SQL Injection攻击

     发生SQL Injection攻击的根源是SQL语句的拼凑方式,如果是通过直接拼接SQL的方式就非常容易发生SQL Injection攻击,SQL Server的SQL语句拼凑还有另一种更加安全的方式:参数查询。如果用户需要创建每次使用不同值的查询,则可以在查询中使用参数。那么这个参数到底是什么呢?其实确切的说,应该把这个参数叫做占位符。即参数是在运行查询时提供值的占位符。在SQLServer数据库中,在需要显示的内容(Select子句)与查询条件(Where子句)中都可以采用参数,从其他地方接收输入的值。不过大部分情况下,都只在查询条件中使用参数。即在单个行或者组的搜索条件中使用参数作为占位符。

    在SQLServer中,参数可以分为两种,即未命名参数与命名参数。通常情况下,如果SQL语句中只需要一个参数的话,那么可以采用未命名参数。如需要查询某个员工上班到现在的全部出勤信息。此时就只需要用到员工编号这个参数即可。此时可以采用未命名的参数。不过有的时候可能查询时需要不止一个参数。如现在需要查询某个员工在4月份的出勤情况。此时就需要两个参数,分别为员工编号、月份。或者需要三个参数,分别为员工编号、开始日期、结束日期等等。总之要多于一个参数。此时就需要使用命名参数。因为如果使用未命名参数的话,则数据库并不知道要把哪个参数对应到哪个地方。所以说,如果要在查询中使用多个参数,那么此时命名参数就会非常有用。

    SqlCommand代表了在SQL Server 数据库中执行的SQL或者存储过程,它有一个属性是Parameters 包含了SQL 语句中用到的参数集合,对于SQL命令中要用到的每一个参数都对应一个SqlParameter对象。添加SqlParameter对象到Parameters集合有两个方法:Add()和AddWithValue()。他们都有多个重载方法,Add()有一系列的重载方法,我一般是使用方法Add(String, SqlDbType),然后单独赋值。

ADO.NET的参数查询到达SQL Server数据库的时候是通过系统存储过程sp_executesql执行的:

exec sp_executesql N'Select * From Products Where ProductID = @ProductID',N'@ProductID int',@ProductID=13

上述查询上包含了参数的数据类型和参数值,传入的值是字符串只是代表了一个文本,而不会成为SQL的一部分,这样就避免了SQL Injection。

通过使用参数查询还有另一个好处是可以提高SQL 的性能,当 SQL Server 会看到 SQL 语句时,它首先检查其缓存中是否存在一个完全相同的语句。 如果找到了一个,它将执行优化的执行计划,以确保尽可能有效地执行该语句。如果它找不到完全匹配,它通过创建一个缓存,在执行语句中使用该执行计划。 您可以看到 sp_executesql 调用的第一部分包含该语句,和它始终都是一样。它的所有后续使用将使用缓存优化的计划。 如果此语句动态生成使用字符串串联,并且在 ProductID 更改的时候,需要创建并为每个值的 ProductID 存储执行计划。 "....WHERE ProductID = 13"与"....WHERE ProductID = 96"不一样。

三、微软发布的3款SQL Injection攻击检测工具

   随着 SQL INJECTION 攻击的明显增多,微软发布了三个免费工具,帮助网站管理员和检测存在的风险并对可能的攻击进行拦截。

  1. Scrawlr :这个微软和 HP合作开发的工具,会在网站中爬行,对所有网页的查询字符串进行分析并发现其中的 SQL INJECTION 风险。Scrawlr 使用了部分 HP WebInspect  相同的技术,但只检测 SQL INJECTION 风险。Scrawlr 从一个起始 URL 入口,爬遍整个网站,并对站点中所有网页进行分析以找到可能存在的漏洞。 下载地址:https://download.spidynamics.com/Products/scrawlr/
  2. Microsoft Source Code Analyzer for SQL Injection:这款被称作 MSCASI 的工具可以检测 ASP 代码并发现其中的 SQL INJECTION 漏洞(ASP 代码以 SQL INJECTION 漏洞著称),你需要向 MSCASI 提供原始代码,MSCASI 会帮你找到存在风险的代码位置。
    下载地址:http://www.microsoft.com/downloads/details.aspx?FamilyId=58A7C46E-A599-4FCB-9AB4-A4334146B6BA&displaylang=en
  3. URLScan  该工具会让 IIS 限制某些类型的 HTTP 请求,通过对特定 HTTP 请求进行限制,可以防止某些有害的请求在服务器端执行。UrlScan 通过一系列关键词发现恶意请求,并阻止恶意请求的执行。 下载地址: http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1697
posted @ 2009-08-29 09:52  张善友  阅读(2820)  评论(7编辑  收藏  举报