SQL注⼊攻击的种类和防范⼿段
观察近来的⼀些安全事件及其后果,安全专家们已经得到⼀个结论,这些威胁主要是通过SQL注⼊造成的。虽然前⾯有许多⽂章讨论了SQL 注⼊,但今天所讨论的内容也许可帮助你检查⾃⼰的,并采取相应防范措施。
SQL注⼊攻击的种类
知彼知⼰,⽅可取胜。⾸先要清楚SQL注⼊攻击有哪些种类。
1.没有正确过滤转义字符
在⽤户的输⼊没有为转义字符过滤时,就会发⽣这种形式的注⼊式攻击,它会被传递给⼀个SQL语句。这样就会导致应⽤程序的终端⽤户对数据库上的语句实施操纵。⽐⽅说,下⾯的这⾏代码就会演⽰这种漏洞:
statement := "SELECT * FROM users WHERE name = '" + userName + "'; "
这种代码的设计⽬的是将⼀个特定的⽤户从其⽤户表中取出,但是,如果⽤户名被⼀个恶意的⽤户⽤⼀种特定的⽅式伪造,这个语句所执⾏的操作可能就不仅仅是代码的作者所期望的那样了。例如,将⽤户名变量(即username)设置为:
a' or 't'='t,此时原始语句发⽣了变化:
SELECT * FROM users WHERE name = 'a' OR 't'='t';
如果这种代码被⽤于⼀个认证过程,那么这个例⼦就能够强迫选择⼀个合法的⽤户名,因为赋值't'='t永远是正确的。
在⼀些SQL服务器上,如在SQL Server中,任何⼀个SQL命令都可以通过这种⽅法被注⼊,包括执⾏多个语句。下⾯语句中的username的值将会导致删除“users”表,⼜可以从“data”表中选择所有的数据(实际上就是透露了每⼀个⽤户的信息)。
a'; DROP TABLE users; SELECT * FROM data WHERE name LIKE '%
这就将最终的SQL语句变成下⾯这个样⼦:
SELECT * FROM users WHERE name = 'a'; DROP TABLE users; SELECT * FROM DATA WHERE name LIKE '%';
其它的SQL执⾏不会将执⾏同样查询中的多个命令作为⼀项安全措施。这会防⽌攻击者注⼊完全独⽴的查询,不过却不会阻⽌攻击者修改查询。
2.Incorrect type handling
如果⼀个⽤户提供的字段并⾮⼀个强类型,或者没有实施类型强制,就会发⽣这种形式的攻击。当在⼀个SQL语句中使⽤⼀个数字字段时,如果没有检查⽤户输⼊的合法性(是否为数字型)就会发⽣这种攻击。例如:
statement := "SELECT * FROM data WHERE id = " + a_variable + "; "
从这个语句可以看出,作者希望a_variable是⼀个与“id”字段有关的数字。不过,如果终端⽤户选择⼀个字符串,就绕过了对转义字符的需要。例如,将a_variable设置为:1; DROP TABLE users,它会将“users”表从数据库中删除,SQL语句变成:SELECT * FROM DATA WHERE id = 1; DROP TABLE users;
3.数据库服务器中的漏洞
有时,数据库服务器软件中也存在着漏洞,如MYSQL服务器中_real_escape_string()函数漏洞。这种漏洞允许⼀个攻击者根据错误的统⼀字符编码执⾏⼀次成功的SQL注⼊式攻击。
4.盲⽬SQL注⼊式攻击
当⼀个Web应⽤程序易于遭受攻击⽽其结果对攻击者却不见时,就会发⽣所谓的盲⽬SQL注⼊式攻击。有漏洞的⽹页可能并不会显⽰数
据,⽽是根据注⼊到合法语句中的逻辑语句的结果显⽰不同的内容。这种攻击相当耗时,因为必须为每⼀个获得的字节⽽精⼼构造⼀个新的语句。但是⼀旦漏洞的位置和⽬标信息的位置被确⽴以后,⼀种称为Absinthe的⼯具就可以使这种攻击⾃动化。
5.条件响应
注意,有⼀种SQL注⼊迫使数据库在⼀个普通的应⽤程序屏幕上计算⼀个逻辑语句的值:
SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=1
这会导致⼀个标准的⾯⾯,⽽语句
SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=2在页⾯易于受到SQL注⼊式攻击时,它有可能给出⼀个不同的结果。如此这般的⼀次注⼊将会证明盲⽬的SQL注⼊是可能的,它会使攻击者根据另外⼀个表中的某字段内容设计可以评判真伪的语句。6.条件性差错
如果WHERE语句为真,这种类型的盲⽬SQL注⼊会迫使数据库评判⼀个引起错误的语句,从⽽导致⼀
个SQL错误。例如:SELECT 1/0 FROM users WHERE username='Ralph'。显然,如果⽤户Ralph存在的话,被零除将导致错误。
7.时间延误
时间延误是⼀种盲⽬的SQL注⼊,根据所注⼊的逻辑,它可以导致SQL引擎执⾏⼀个长队列或者是⼀个时间延误语句。攻击者可以衡量页⾯加载的时间,从⽽决定所注⼊的语句是否为真。
以上仅是对SQL攻击的粗略分类。但从技术上讲,如今的SQL注⼊攻击者们在如何出有漏洞的⽹站⽅⾯更加聪明,也更加全⾯了。出现了⼀些新型的SQL攻击⼿段。⿊客们可以使⽤各种⼯具来加速漏洞的利⽤过程。我们不妨看看the Asprox Trojan这种⽊马,它主要通过⼀个发布邮件的僵⼫⽹络来传播,其整个⼯作过程可以这样描述:⾸先,通过受到控制的主机发送的垃圾邮件将此⽊马安装到电脑上,然后,受到此⽊马感染的电脑会⼀段⼆进制代码,在其启动时,它会使⽤搜索引擎搜索⽤微软的ASP技术建⽴表单的、有漏洞的⽹站。搜索的结果就成为SQL注⼊攻击的靶⼦清单。接着,这个⽊马会向这些站点发动SQL注⼊式攻击,使有些⽹站受到控制、破坏。访问这些受到控制和破坏的⽹站的⽤户将会受到欺骗,从另外⼀个站点下载⼀段恶意的Script代码。最后,这段代码将⽤户指引到第三个站点,这⾥有更多的恶意软件,如窃取⼝令的⽊马。
以前,我们经常警告或建议Web应⽤程序的程序员们对其代码进⾏测试并打补丁,虽然SQL注⼊漏洞被
发现和利⽤的机率并不太⾼。但近来攻击者们越来越多地发现并恶意地利⽤这些漏洞。因此,在部署其软件之前,⼈员应当更加主动地测试其代码,并在新的漏洞出现后⽴即对代码打补丁。
防御和检查SQL注⼊的⼿段
1.使⽤参数化的过滤性语句
要防御SQL注⼊,⽤户的输⼊就绝对不能直接被嵌⼊到SQL语句中。恰恰相反,⽤户的输⼊必须进⾏过滤,或者使⽤参数化的语句。参数化的语句使⽤参数⽽不是将⽤户输⼊嵌⼊到语句中。在多数情况中,SQL语句就得以修正。然后,⽤户输⼊就被限于⼀个参数。下⾯是⼀个使⽤Java和JDBC API例⼦:
PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE PASSWORD=?");
注入
prep.setString(1, pwd);
总体上讲,有两种⽅法可以保证应⽤程序不易受到SQL注⼊的攻击,⼀是使⽤代码复查,⼆是强迫使⽤参数化语句的。强迫使⽤参数化的语句意味着嵌⼊⽤户输⼊的SQL语句在运⾏时将被拒绝。不过,⽬前⽀持这种特性的并不多。如H2 数据库引擎就⽀持。
2.还要避免使⽤解释程序,因为这正是⿊客们借以执⾏⾮法命令的⼿段。
3.防范SQL注⼊,还要避免出现⼀些详细的错误消息,因为⿊客们可以利⽤这些消息。要使⽤⼀种标准的输⼊确认机制来验证所有的输⼊数据的长度、类型、语句、企业规则等。
4.使⽤专业的漏洞扫描⼯具。但防御SQL注⼊攻击也是不够的。攻击者们⽬前正在⾃动搜索攻击⽬标并实施攻击。其技术甚⾄可以轻易地被应⽤于其它的Web架构中的漏洞。企业应当投资于⼀些专业的漏洞扫描⼯具,如⼤名⿍⿍的Acunetix的Web漏洞扫描程序等。⼀个完善的漏洞扫描程序不同于⽹络扫描程序,它专门查⽹站上的SQL注⼊式漏洞。最新的漏洞扫描程序可以查最新发现的漏洞。
5.最后⼀点,企业要在Web应⽤程序开发过程的所有阶段实施代码的安全检查。⾸先,要在部署Web应⽤之前实施,这种措施的意义⽐以前更⼤、更深远。企业还应当在部署之后⽤漏洞扫描⼯具和站点监视⼯具对⽹站进⾏测试。
Web安全拉警报已经响起,安全形式异常严峻,企业绝对不应当草率从事。安全重于泰⼭!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。