类型强制,就会发生这种形式的攻击。当在一个SQL语句中使用一个数字字段时,如果程序员没有检查用户输入的合法性(是否为数字型)就会发生这种攻击。例如: SELECT * FROM data WHERE id = \ 从这个语句可以看出,作者希望a_variable是一个与“id”字段有关的数字。不过,如果终端用户选择一个字符串,就绕过了对转义字符的需要。例如,将a_variable设置为: 1; DROP TABLE users
它会将“users”表从数据库中删除
SELECT * FROM DATA WHERE id = 1; DROP TABLE users; 解决方案:
对输入进行验证。验证是确保数据以被许可的方式递交。要使用一种标准的输入确认机制来验证所有的输入数据的长度、类型、语句、企业规则等。比如int类型的数据不能输入字符串,输入长度应在一定的长度内,电子邮件地址包含@符号等。验证通常以两种方式执行:一是列出危险字符或不受欢迎字符的黑名单;二是列出给定字符的名单,后者需要编程人员花费更多心思。
三:条件响应
部分对SQL注入有一点了解的程序员,认为只要把单引号过滤掉就安全了,这种情况不为少数,如果你用单
引号测试,是测不到注入点的
那么,什么样的测试方法才是比较准确呢?答案如下: ① http://www.19cn.com/showdetail.asp?id=49 ② http://www.19cn.com/showdetail.asp?id=49 and 1=1 ③ http://www.19cn.com/showdetail.asp?id=49 and 1=2 这就是经典的1=1、1=2测试法了,怎么判断呢?看看上面三个网址返回的结果就知道了: 可以注入的表现:
① 正常显示(这是必然的,不然就是程序有错误了) ② 正常显示,内容基本与①相同
③ 提示BOF或EOF(程序没做任何判断时)、或提示找不到记录(判断了rs.eof时)、或显示内容为空(程序加了on error resume next)
不可以注入就比较容易判断了,①同样正常显示,②和③一般都会有程序定义的错误提示,或提示类型转换时出错。
当然,这只是传入参数是数字型的时候用的判断方法,实际应用的时候会有字符型和搜索型参数,需要再次进行猜测。
不同的数据库的函数、注入方法都是有差异的,所以在注入之前,我们还要判断一下数据库的类型。一般ASP最常搭配的数据库是Access和SQLServer,网上超过
99%的网站都是其中之一。
怎么让程序告诉你它使用的什么数据库呢?来看看: SQLServer有一些系统变量,如果服务器IIS提示没关闭,并且SQLServer返回错误提示的话,那可以直接从出错信息获取,方法如下:
http://www.19cn.com/showdetail.asp?id=49 and user>0 这句语句很简单,但却包含了SQLServer特有注入方法的精髓,是一种效率极高的猜解方法。让我看来看看它的含义:首先,前面的语句是正常的,重点在and user>0,我们知道,user是SQLServer的一个内置变量,它的值是当前连接的用户名,类型为nvarchar。拿一个nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQLServer的出错提示是:将nvarchar值 ”abc” 转换数据类型为 int 的列时发生语法错误,呵呵,abc正是变量user的值,这样,不废吹灰之力就拿到了数据库的用户名。类似的例子还有很多,下面说明针对此例子的解决方案。 解决方案:要避免出现一些详细的错误消息(如系统文件路径,内部IP地址等),因为黑客们可以利用这些消息。同时出现错误可以跳转到错误页面或者退出登录,而不是显示详细错误信息