SQL Injection(SQL注入)介绍及SQL Injection攻击检测工具

上一篇 / 下一篇  2010-01-27 14:05:19 / 个人分类:SQL 注入

SQL Injection(SQL注入)介绍及SQL Injection攻击检测工具(转载 开着拖拉机上班  系统组)

1.关于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语句:
update tableName set columnName1 = " $Client_Submit_Data " where PK_ID = 1234

$Client_Submit_Data是一个变量,它代表客户端提交的数据,这里我就不管环境是ASP还 是PHP还是其他什么东西了。
假设这个操作是要更新一篇文章的标题,很多人是不是会这么构造SQL语句?我们看看$Cl ient_Submit_Data包含引号的情况,令$Client_Submit_Data = 谁能告诉我"sql injecti on"是什么?
那么sql语句将被拼凑成这样:
update tableName set columnName1 = "谁能告诉我"sql injection"是什么?" where PK_ID = 1234
执行结果很明显,将执行这样的语句:update tableName set columnName1 = "谁能告诉我"
where子句被忽略掉了,很遗憾,你的数据库中所有文章标题都会被update为"谁能告诉我 "

在这个例子当中,用户应该是无心的——标题里面包括引号应该很正常吧——但结果却和SQL Injection无异。

好啦,说了半天废话,言归正传,说一下如何应对这种问题。

我相信这里的朋友都看过很多防止SQL Injection的文章了,也大都会通过replace来防范一些注入,问题是:你们知其然的时候是否知其所以然?

我认为,彻底解决SQL Injection的最好方法是:避免拼凑SQL语句。这就是我在上面要大家特别注意拼凑这个词的原因。
SQL Injection之所以有机可乘,是因为绝大多数Server Application采用拼凑SQL语句的方式来构建应用程序(阅读这个帖子的诸位,你们回首想想自己的项目,有几个不是通过拼凑SQL语句的方式来操作数据库?想想你们见过的被注入的案例,有几个不是采用的拼凑SQL语句的应用),所谓拼凑SQL语句,简单一点说就是:用连接字符串操作(ASP中的&和PHP中的.)将SQL关键字和客户端提交的数据连接起来并发送给DBMS执行。这样做直接导致 DBMS根本不知道你计划(plan to)做什么,而只知道你要(is to)做什么,不是吗,服务器端脚本总是将要执行的SQL语句构造好,然后发给数据库,DBMS根本不知道客户端数据 替换了变量之后,这个语句的执行计划是否有变化。服务器端脚本总是粗暴的告诉DBMS:你只管这么做好了,别问我为什么。就像上面我提到的更新文章标题的例子,DBMS不知道你只想更新第1234篇文章的标题,它以为你就是要把所有的标题都变成这个,因为你的语句就是没有where子句嘛!

说到这里,可能大家都明白了,所谓的最好方法是Stored Procedure。Yes! That is!

要想做出安全可靠的Server application,你最好把自己当作两个人,一个DBA,一个Coder(ASP Coder,PHP Coder or others),很多人往往只知道:我在做一个BBS,我在做一个留言本,我在做一个新闻发布系统,我们的流程都是这样的,给用户一个表单,让用户提交,然后去写数据库,用的时候根据条件把数据记录找出来,然后显示。没事,如果你 是一个业余爱好者,只想自己写点小东西玩玩,这足够了!如果你想把WebDev作为你的职业,或者说,你想成为一个非常专业的业余爱好者,你必须当自己是一个DBA+Coder,至于要不要是一个Designer就看你的能力和精力咯!

好了,点到为止,我就说这么多,彻底的解决方法是要在DBMS上写入你的数据操作计划,让服务器在开始执行之前知道你的意图,不要粗暴的告诉它:我就是要你执行这个命令,不要问我为什么!

实现方法嘛,目前比较普遍的,也比较容易实现的就是存储过程了,应用存储过程不仅可以从根本上解决SQL Injection这个安全问题,还会使得你的应用程序速度成倍增长(这个增长的幅度甚至可能达到一个数量级,这跟很多因素有关,不好一概而论),还会使得你开发的系统更想大型系统,拥有更好的架构体系(例如MVC模式)。

MySQL 4.1.x及其后续版本和ODBC中,提供了一种叫做prepared statements的东西,它 本质上也是一种存储过程,一种系统预置(相对于用户自定义)的存储过程。

如果你没有条件用上存储过程(比如数据库不支持,MySQL,Access,SQLite等都不支持),那么就只能将SQL Injection扼杀在摇篮里了。解决方法,我也只简单的说一句:不要相信任何来自客户端的数据。这个客户端的数据,可以通过很多途径被提交,比如get,post ,cookie,browser参数,IP地址,等等,只要不是服务器上获取的就都算客户端数据,只要是客户端数据,都是不可信的,在TCP/IP这个大框架下,什么都是可以伪造的,包括IP地址。

凡是来自客户端的数据,必须校验——注意是校验,不是过滤。基本上,不管你多聪明多细心(哪怕像我一样,不许笑,不许笑,严肃点,严肃点,我们这儿讲SQL Injection呢) 也无法穷举可能被用于SQL Injection的符号和关键字,也无法预知替换掉他们是否会有副 作用,最好的办法是不去判断什么数据不符合条件,而改由判断什么数据符合条件,假设你的一个系统用户名只能是字母数字和下划线,那么你就可以用[0-9a-zA-Z_]+这个正则来匹配它,如果不符合条件,拒之即可,这比费尽心思去过滤单引号分号逗号空格什么的要明了和简洁的多。

当然如果你嫌存储过程麻烦,你也可以使用参数化SQL语句,至少在asp.net可以这么做,请见本人的一篇文章:《在ADO.NET中使用参数化SQL语句的大同小异》,网址是:http://blog.csdn.net/zhoufoxcn/archive/2008/03/19/2195618.aspx,介绍在asp.net中使用参数化SQL语句应注意的事项。

春节前夕,数万个用PHPBB作为论坛的网站被攻陷,大家有印象吗?罪魁祸首只是一个单引 ,尽管PHP有magic_quotes_gpc,可还是被干掉了,原因是%2527在url_decode函数中会被解析为%27(因为%25就是百分号),%27正是引号,By the way,尽管博客中国的论坛也 是基于PHPBB的,但是那次我们幸免于难,因为在那之前我们被黑过一次了(汗),就是因为这个,哈哈! 其实,SQL Injection不是ASP编程领域特有的,Web开发最容易碰到,但Desktop Application也有,只要有数据库的地方,只要采用拼凑SQL语句的方式,就可能存在Injection的机会,大家牢记,如果有条件,尽量把数据DBMS职责范围的事情交给DBMS去做,如果没条件,一定要注意校验客户端提交的数据,当然,双管齐下也行,^_^

好了,最后,说句话给那些有志于从事WebDev工作的朋友,如果将来你进入这个领域,你把总结出来这篇文章,你应该会很顺利的通过面试,并得到一个不错的薪水等级。

附:微软发布3款SQL Injection攻击检测工具

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

Scrawlr
下载地址:https://download.spidynamics.com/Products/scrawlr/

这个微软和 HP合作开发的工具,会在网站中爬行,对所有网页的查询字符串进行分析并发现其中的 SQL INJECTION 风险。Scrawlr 使用了部分 HP WebInspect 相同的技术,但只检测 SQL INJECTION 风险。Scrawlr 从一个起始 URL 入口,爬遍整个网站,并对站点中所有网页进行分析以找到可能存在的漏洞。

Microsoft Source Code Analyzer for SQL Injection
下载地址:http://www.microsoft.com/downloads/details.aspx?FamilyId=58A7C46E-A599-4FCB-9AB4-A4334146B6BA&displaylang=en

这款被称作 MSCASI 的工具可以检测 ASP 代码并发现其中的 SQL INJECTION 漏洞(ASP 代码以 SQL INJECTION 漏洞著称),你需要向 MSCASI 提供原始代码,MSCASI 会帮你找到存在风险的代码位置。

URLScan 3.0
下载地址:http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1697

该工具会让 IIS 限制某些类型的 HTTP 请求,通过对特定 HTTP 请求进行限制,可以防止某些有害的请求在服务器端执行。UrlScan 通过一系列关键词发现恶意请求,并阻止恶意请求的执行。

在最近两年中,安全专家应该对网络应用层的攻击更加重视。因为无论你有多强壮的防火墙规则设置或者非常勤于补漏的修补机制,如果你的网络应用程序开发者没有遵循 安全代码进行开发,攻击者将通过80端口进入你的系统。广泛被使用的两个主要攻击技术SQL注入[ref1]和CSS[ref2]攻击。SQL注入是指:通过互联网的输入区域,插入SQL meta-characters(特殊字符 代表一些数据)和指令,操纵执行后端的SQL查询的技术。这些攻击主要针对其他组织的WEB服务器。CSS攻击通过在URL里插入scrīpt标签,然后 诱导信任它们的用户点击它们,确保恶意Javascrīpt代码在受害人的机器上运行。这些攻击利用了用户和服务器之间的信任关系,事实上服务器没有对输入、输出进行检测,从而未拒绝javascrīpt代码。

这篇文章讨论SQL注入和CSS攻击漏洞的检测技术。网上已经有很多关于这两种基于WEB攻击的讨论,比如如何实施攻击,他们的影响,怎样更好的编制和设计程序防止这些攻击。 然而, 对如何检测这些攻击并没有足够的讨论。我们采用流行的开源的IDS Snort[ref 3],组建根据检测这些攻击的规则的正则表达式。附带,Snort默认规则设定包含检测CSS的方法,但是这些容易被避开检测。比如大多通过hex进制编码,如%3C%73%63%72%69%70% 74%3E代替<scrīpt>避开检测。

依赖level of paranoia组织的能力,我们已经编写了多种检测相同攻击的规则。如果你希望检测各种可能的SQL注入攻击,那么你需要简单的留意任何现行的SQL meta-characters,如单引号,分号和双重破折号。同样的一个极端检测CSS攻击的方法,只要简单地提防HTML标记的角括号。但这样会检测 出很多错误。为了避免这些,这些规则需要修改使它检测更精确些, 当仍然不能避免错误。

在Snort规则中使用pcre(Perl Compatible Regular Expressions)[ref4]关键字,每个规则可以带或不带其他规则动作。这些规则也可以被公用软件如grep(文档搜索工具)使用,来审阅网络服务器日志。 但是,需要警惕的是,用户的输入只有当以GET提交请求时,WEB服务器才会记录日记,如果是以POST提交的请求在日记中是不会记录的。

2. SQL注入的正则表示式
当 你为SQL注入攻击选择正则表示式的时候,重点要记住攻击者可以通过提交表单进行SQL注入,也可以通过Cookie区域。你的输入检测逻辑应该考虑用户 组织的各类型输入(比如表单或Cookie信息)。并且如果你发现许多警告来自一个规则,请留意单引号或者是分号,也许些字符是你的Web应用程序创造的 合法的在CookieS中的输入。因此, 您需要根据你的特殊的WEB应用程序评估每个规则。

依照前面提到,一个琐细的检测SQL射入攻击的正则表达式要留意SQL特殊的meta-characters 譬如单引号(’)双重扩则号(--),为了查出这些字符和他们hex等值数, 以下正则表达式适用:

2.1 检测SQL meta-characters的正则表达式
/(\%27)|(\’)|(\-\-)|(\%23)|(#)/ix

解释:
我 们首先检查单引号等值的hex,单引号本身或者双重扩折号。这些是MS SQL Server或Oracle的字符, 表示后边的为评论, 随后的都将被忽略。 另外,如果你使用MySQL,你需要留意 ’#’和它等值的hex的出现。注意我们不需要检查双重破折号等值的hex, 因为这不是HTML meta-character, 浏览器不会进行编码。 并且, 如果攻击者设法手工修改双重破折号为它的hex值%2D(使用代理像Achilles[ref 5]), SQL注入将失败。
加入上述正则表达式的新的Snort规则如下:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SQL Injection - Paranoid"; flow:to_server,established;uricontent:".pl";pcre:"/(\%27)|(\’)|(\-\-)|(%23)|(#)/i"; classtype:Web-application-attack; sid:9099; rev:5;)

在本篇讨论中, uricontent关键字的值为".pl ", 因为在我们的测试环境里, CGI 程序是用Perl写的。uricontent关键字的值取决于您的特殊应用, 这个值也许是".php ", 或" .asp ", 或" .jsp ", 等。 从这点考虑, 我们不显示对应的Snort 规则, 但是我们会给出创造这些规则的正则表达式。 通过这些正则表达式你可以很简单的创造很多的Snort规则.在前面的正则表达式里, 我们检测双重破折号是因为:即便没有单引号的存在那里也可能是SQL射入点[ref 6]。 例如, SQL查询条目只包含数值,如下:

select value1, value2, num_value3 from database
where num_value3=some_user_supplied_number

这种情况,攻击者可以执行额外的SQL查询, 示范提交如下输入:

3; insert values into some_other_table

最后, pcre的修饰符’ i’ 和’ x ’ 是用于分别匹配大小写和忽略空白处的。 上面的规则也可以另外扩展来检查分号的存在。然而,分号很可以是正常HTTP应答的一部分。为了减少这种错误,也是为了任何正常的单引号和双重扩折号的出

现,上面的规则应该被修改成先检测=号的存。用户输入会响应一个GET或POST请求,一般输入提交如下:

username=some_user_supplied_value&password=some_user_supplied_value

因此, SQL 注入尝试将导致用户的输入出现在a = 号或它等效的hex值之后。

2.2 修正检测SQL meta-characters的正则表达式

/((\%3D)|(=))[^\n]*((\%27)|(\’)|(\-\-)|(\%3B)|(:))/i

解释:
这个规则首先留意 = 号或它的hex值(%3D),然后考虑零个或多个除换行符以外的任意字符,最后检测单引号,双重破折号或分号。

典型的SQL注入会尝试围绕单引号的用途操作原来的查询,以便得到有用的价值。讨论这个攻击一般使用1’or’1’=’1字符串. 但是, 这个串的侦查很容易被逃避,譬如用1’or2>1 --. 然而唯一恒定的部分是最初的字符的值,跟随一单引号,再加’or’。随后的布尔逻辑可能在一定范围上变化,可以是普通样式也可能是非常复杂的。这些攻击可以相当精确被侦测,通过以下的正则表达式。2.3章节讲解。

2.3 典型的 SQL 注入攻击的正则表达式

/\w*((\%27)|(\’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

解释:
\w* - 零个或多个字符或者下划线。
(\%27)|\’ - 单引号或它的hex等值。
(\%6 F)|o|(\%4 F))((\%72)|r|-(\%52) -‘or’的大小写以及它的hex等值。

’union’SQL 查询在SQL注入各种数据库中攻击中同样是很常见的。如果前面的正则表达式仅仅检测单引号或则其他的SQL meta. characters ,会造成很多的错误存在。你应该进一步修改查询,检测单引号和关键字‘union’。这同样可以进一步扩展其他的SQL关键字,像’select’, ’insert’, ’update’, ’delete’, 等等。

2.4 检测SQL注入,UNION查询关键字的正则表达式

/((\%27)|(\’))union/ix

(\%27)|(\’) - 单引号和它的hex等值
union - union关键字

可以同样为其他SQL查询定制表达式,如 >select, insert, update, delete, drop, 等等.

如 果,到这个阶段,攻击者已经发现web应用程序存在SQL注入漏洞,他将尝试利用它。如果他认识到后端服务器式MS SQL server,他一般会尝试运行一些危险的储存和扩展储存过程。这些过程一般以‘sp’或‘xp’字母开头。典型的,他可能尝试运行 ‘xp_cmdshell’扩展储存过程(通过SQL Server执行Windows命令)。SQL服务器的SA权限有执行这些命令的权限。同样他们可以通过xp_regread, xp_regwrite等储存过程修改注册表。

2.5 检测MS SQL Server SQL注入攻击的正则表达式

/exec(\s|\+)+(s|x)p\w+/ix

解释:
exec - 请求执行储存或扩展储存过程的关键字
(\s|\+)+ - 一个或多个的空白或它们的http等值编码
(s|x) p- ‘sp’或‘xp’字母用来辨认储存或扩展储存过程
\w+ - 一个或多个字符或下划线来匹配过程的名称

3. 跨站脚本(CSS)的正则表达式

当发动CSS攻击或检测一个网站漏洞的时候, 攻击者可能首先使简单的HTML标签如<b>(粗体),<i>(斜体)或<u>(下划线),或者他可能尝试简单的 scrīpt标签如<scrīpt>alert("OK")</scrīpt>. 因为大多数出版物和网络传播的检测网站是否有css漏洞都拿这个作为例子。这些尝试都可以很简单的被检测出来。然而,高明点的攻击者可能用它的hex值替换整个字符串。这样<scrīpt>标签会以%3C%73%63%72%69%70%74%3E出现。另一方面,攻击者可能使用web代理服务器像Achilles会自动转换一些特殊字符如<换成%3C、>换成%3E.这样攻击发生时,URL 中通常以hex等值代替角括号。

下列正则表达式将检测任何文本中包含的html的<、>。它将捉住试图使用< b>、<u>、或<scrīpt>。这正则表达式应该忽略大小写。我们需要同时检测角括号和它的hex等值(% 3C|<)。检测hex进制转化的整个字符串,我们必须检测用户输入的数字和%号,即使用[a-z0-9%] 。这可能会导致一些错误出现,不是大部分会检测到真实攻击的。

3.1 一般 CSS 攻击的正则表达式

/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/ix

解释:
((\%3C)|<) -检查<和它hex等值
((\%2F)|\/)*-结束标签/或它的 hex等值
[a-z0-9\%]+ -检查标签里的字母或它hex等值
((\%3E)|>) -检查>或它的hex等值

Snort 规则:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NII Cross-site scrīpting attempt"; flow:to_server,established; pcre:"/((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)/i"; classtype:Web-application-attack; sid:9000; rev:5;)

跨站脚本同样可以使用<img src=>技术。现行默认的snort规则可以被轻易避开。

3.2章节提供了防止这种技术的方法。

3.2 "<img src" CSS 攻击正则表达式

/((\%3C)|<)((\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47))[^\n]+((\%3E)|>)/I

解释:
(\%3 C)|<) -<或它的hex等值
(\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47) -’img’字母或它的大小写hex等值的变化组合
[^\n]+ -除了换行符以外的任何跟随<img的字符
(\%3E)|>) ->或它的hex等值

3.3 CSS 攻击的极端的正则表达式

/((\%3C)|<)[^\n]+((\%3E)|>)/I

解释:
这个规则简单寻找<+除换行符外的任何字符+>。由于你的web服务器和web应用程序的构架,这个规则可能产生一些错误。但它能保证捉住任何CCS或者类似CSS的攻击。

一个不错避开过滤的CSS方法请参考Bugtraq投稿的
http://www.securityfocus.com/archive/1/272...rchive/1/272037.
但是请注意最后一种极端的规则将能检测这所有的攻击。

总结:

在 这篇文章中,我们提出了不同种类的正则表达式规则来检测SQL注入和跨站脚本攻击。有些规则简单而极端,一个潜在的攻击都将提高警惕。但这些极端的规则可 能导致一些主动的错误。考虑到这点,我们修改了这些简单的规则,利用了另外的样式,他们可以检查的更准确些。在这些网络应用成的攻击检测中,我们推荐将这 些作为调试你IDS或日志分析方法的起点。再经过几次修改后,在你对正常网交易部分的非恶意应答进行评估以后,你应该可以准备的检测那些攻击了。

参考
1. SQL Injection

http://www.spidynamics.com/papers/SQLInjectionWhitePaper.pdf
2. Cross Site scrīpting FAQ http://www.cgisecurity.com/articles/xss-

faq.shtml
3. The Snort IDS http://www.snort.org
4. Perl-compatible regular expressions (pcre) http://www.pcre.org
5. Web application proxy, Achilles http://achilles.mavensecurity.com
3. Advanced SQL Injection

http://www.nextgenss.com/papers/advanced_sql_injection.pdf
7. Secure Programming HOWTO, David Wheeler www.dwheeler.com
8. Threats and Countermeasures, MSDN, Microsoft


TAG:

 

评分:0

我来说两句

日历

« 2024-04-25  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 17017
  • 日志数: 19
  • 建立时间: 2009-07-31
  • 更新时间: 2010-06-24

RSS订阅

Open Toolbar