日前sql injection的攻击测试愈演愈烈,很多大型的网站和论坛都相继被注入。这些网站一般使用的多为sql server数据库,正因为如此,很多人开始怀疑sql server的安全性。其实sql server 2000已经通过了美国政府的c2级安全认证-这是该行业所能拥有的最高认证级别,所以使用sql server还是相当的安全的。当然和orcal、db2等还是有差距,但是sql server的易用性和广泛性还是能成为我们继续使用下去的理由。那怎么样才能使sql server的设置让人使用的放心呢?
第一步肯定是打上sql server最新的安全补丁,现在补丁已经出到了sp3。下载地址:http://www.microsoft.com/sql/downloads/2000/sp3.asp。如果这一步都没有做好,那我们也没有继续下去的必要了。
第二步是修改默认的1433端口,并且将sql server隐藏。这样能禁止对试图枚举网络上现有的 sql server 客户端所发出的广播作出响应。另外,还需要在tcp/ip筛选中将1433端口屏蔽掉,尽可能的隐藏你的sql server数据库。这样子一但让攻击创建了sql server的账号,也不能马上使用查询分析器远程登陆来进行下一步的攻击。单从asp,php等页面构造恶意语句的话,还有需要查看返回值的问题,总比不上直接查询分析器来得利落。所以我们首先要做到即使让别人注入了,也不能让攻击者下一步做得顺当。修改方法:企业管理器 --> 你的数据库组 --> 属性 --> 常规 --> 网络配置 --> tcp/ip --> 属性 ,在这儿将你的默认端口进行修改,和sql server的隐藏。
第三步是很重要的一步,sql injection往往在web code中产生。而做为系统管理员或者数据库管理员,总不能常常的去看每一段代码。即使常常看代码,也不能保证我们在上面的疏忽。那怎么办?我们就要从数据库角色着手,让数据库用户的权限划分到最低点。sql server的默认权限让人真的很头疼,权限大得非常的高,权限小的又什么都做不了,sysadmin和db_owner真是让人又爱又恨。攻击者一但确认了网站存在sql injection漏洞,肯定有一步操作步骤就是测试网站的sql server使用者具有多大的权限。一般都会借助select is_srvrolemember('sysadmin'),或者select is_member('db_owner'),再或者用user = 0(让字符和数字进行比较,sql server就会提示了错误信息,从该信息中即可知道一些敏感信息)等语句进行测试。方法还有,我也不敢多说了。其一怕错,其二怕联盟中的人扁。在当前,如果网站的数据库使用者用的是sa权限,再加上确认了web所处在的绝对路径,那么就宣告了你的网站的over。db_owner权限也一样,如果确认了绝对路径,那么有50%的机会能给你的机器中上web 方式的木马,如海阳等。所以这儿我们确认了一点,我们必须要创建自已的权限,让攻击者找不着下嘴的地方。在这儿引用一个sql server联机帮助中的例子:
创建 sql server 数据库角色的方法(企业管理器)
创建 sql server 数据库角色
1. 展开服务器组,然后展开服务器。
2. 展开"数据库"文件夹,然后展开要在其中创建角色的数据库。
3. 右击"角色",然后单击"新建数据库角色"命令。
4. 在"名称"框中输入新角色的名称。
5. 单击"添加"将成员添加到"标准角色"列表中,然后单击要添加的一个或多个用户。(可选)
只有选定数据库中的用户才能被添加到角色中。
对象权限
处理数据或执行过程时需要称为对象权限的权限类别:
· select、insert、update 和 delete 语句权限,它们可以应用到整个表或视图中。
· select 和 update 语句权限,它们可以有选择性地应用到表或视图中的单个列上。
· select 权限,它们可以应用到用户定义函数。
· insert 和 delete 语句权限,它们会影响整行,因此只可以应用到表或视图中,而不能应用到单个列上。
· execute 语句权限,它们可以影响存储过程和函数。
语句权限
创建数据库或数据库中的项(如表或存储过程)所涉及的活动要求另一类称为语句权限的权限。例如,如果用户必须能够在数据库中创建表,则应该向该用户授予 create table 语句权限。语句权限(如 create database)适用于语句自身,而不适用于数据库中定义的特定对象。
语句权限有:
· backup database
· backup log
· create database
· create default
· create function
· create procedure
· create rule
· create table
· create view
暗示性权限
暗示性权限控制那些只能由预定义系统角色的成员或数据库对象所有者执行的活动。例如,sysadmin 固定服务器角色成员自动继承在 sql server 安装中进行操作或查看的全部权限。
数据库对象所有者还有暗示性权限,可以对所拥有的对象执行一切活动。例如,拥有表的用户可以查看、添加或删除数据,更改表定义,或控制允许其他用户对表进行操作的权限。
db_owner 在数据库中有全部权限。
db_accessadmin 可以添加或删除用户 id。
db_securityadmin 可以管理全部权限、对象所有权、角色和角色成员资格。
db_ddladmin 可以发出 all ddl,但不能发出 grant、revoke 或 deny 语句。
db_backupoperator 可以发出 dbcc、checkpoint 和 backup 语句。
db_datareader 可以选择数据库内任何用户表中的所有数据。
db_datawriter 可以更改数据库内任何用户表中的所有数据。
db_denydatareader 不能选择数据库内任何用户表中的任何数据。
db_denydatawriter 不能更改数据库内任何用户表中的任何数据。
在这儿把新建的数据库角色的权限配置好,比如需要使用哪个表、视图、存储过程等。然后把db_owner和db_securityadmin、db_backupoperator取消,不给攻击者backup database和create table的机会,一但攻击者具有这两个权限,那么你的网站就还处在十分危险的状态。还有注意一下,在创建数据库账号时,千万不能对服务器角色进行选择。
第四步是修改sql server内置存储过程。sql server估计是为了安装或者其它方面,它内置了一批危险的存储过程。能读到注册表信息,能写入注册表信息,能读磁盘共享信息等等……各位看到这儿,心里可能会在想,我的网站中有其它的代码,又不像查询分析器那样能查接将结果输出。给你这个权限,又不能怎么样,还是看不到信息。如果各位这样想就大错特错了。提示一下,如果攻击者有create table的权限,那么创建一个临时表,然后将信息insert到表中,然select出来,接着跟数字进行比较,让sql server报错,那么结果就全出来了……所以我们要报着宁错杀,不放过的态度进行修补。
先来列出危险的内置存储过程:
xp_cmdshell
xp_regaddmultistring
xp_regdeletekey
xp_regdeletevalue
xp_regenumkeys
xp_regenumvalues
xp_regread
xp_regremovemultistring
xp_regwrite
activex自动脚本:
sp_oacreate
sp_oadestroy
sp_oamethod
sp_oagetproperty
sp_oasetproperty
sp_oageterrorinfo
sp_oastop
以上各项全在我们封杀之列,例如xp_cmdshell屏蔽的方法为:sp_dropextendedproc 'xp_cmdshell',如果需要的话,再用sp_addextendedproc 'xp_cmdshell', 'xpsql70.dll'进行恢复。如果你不知道xp_cmdshell使用的是哪个.dll文件的话,可以使用sp_helpextendedproc xp_cmdshell来查看xp_cmdshell使用的是哪个动态联接库。另外,将xp_cmdshell屏蔽后,我们还需要做的步骤是将xpsql70.dll文件进行改名,以防止获得sa的攻击者将它进行恢复。
我们做到这儿,你的sql server就基本上安全了。但是信息还是能一样的外泄。毕竟select我们是无法取消的,除非你的网站用的是html。sql injection的防范还需要我们这些程序员来注意,这才是治本之法。我们在高级设置篇再接着对sql server的安全做下一步的分析。该篇文章如果有什么错漏,请大家多多包涵。谢谢……
另外推荐一下,sql injection的测试工具nbsi2,这是由联盟中小竹同志开发,对sql injection的注入有代表性的作用,另外一个就是小弟的nbwebshell了。这些工具都可以到联盟网站进行下载
nb联盟-jadesun(裤衩) qq:280155
nb网站:www.54nb.com
sql注入防御方法-程序员篇
作者:nb联盟-小竹
sql注入越来越多的被利用来入侵网站,部分web程序员也开始关注这方面的知识,但由于对入侵的方法一知半解,导致在过滤的时候漏掉某些字符,造成安全漏洞;或者是草木皆兵,把一些合法的用户请求都拒之门外,试想一下,当用户想输入个i'm a boy的时候,却给你臭骂一顿,他还会愿意再上你的网站吗?
下面,我从程序方面介绍一下sql注入的防御方法,首先看这三句最简单sql语句
1.sql="select * from users where userid=" & request("id")
2.sql="select * from users where userid='" & request("id") & "'"
3.sql="select * from users where username like '%" & request("name") & "%'"
第一句,参数是数字型,这个很明显。第二句,如果字段userid是int型,就有些人分不清楚了。其实,区分第数字弄和字符型参数,只要看sql语句参数两边有没有单引号即可,很明显,第一句没单引号,是数字型;第二第三句有单引号,是字符型。
对于数字型变量,传入的参数都会直接附加到sql语句上执行,而因为参数是数字型,所以用isnumeric判断是很安全的,我曾经试过用/0之类试图断开参数,但结果都是失败。
对于字符型变量,传入的参数都是做为常量,比如你传1 and 1=1进去,sql语句就是userid='1 and 1=1',在单引号界定范围里面的值永远都只是一个常量,要打破这个范围,唯一的字符就是界定的字符:单引号。所以,字符型变量只要过滤了'号就完全安全了,至于如何过滤,最好是把一个单引号替换成两个单引号,因为sql语句里面规定,'常量'这样表示的常量里面,常量里面如果要有单引号,可以用两个单引号代替。这样,既可以保持用户输入的原貌,又可以保证程序的安全。
下面是两个函数,大家可以copy过去直接调用就行了。
'---------------------------------------------------------------
' nb联盟防注入函数 reqnum / reqstr
'---------------------------------------------------------------
function reqnum ( strname )
reqnum = request ( strname )
if not isnumeric ( reqnum ) then
response.write "参数必须为数字型!"
response.end
end if
end function
function reqstr ( strname )
reqstr = replace ( request(strname), "'", "''" )
end function
以上面三句sql语句,说明一下调用方法:
1.sql="select * from users where userid=" & reqnum("id")
2.sql="select * from users where userid='" & reqstr("id") & "'"
3.sql="select * from users where username like '%" & reqstr("name") & "%'"
重申一点:上面的方法无论对sqlserver库还是access或是其它数据库,都是绝对适用、绝对安全,但注意一点,sqlserver的存储过程是个例外,该情况下要把单引号替换成四个单引号,以保安全。
另外,nb联盟-裤衩曾经写过一篇sqlserver安全设置的文章,在程序有漏洞的时候,该文章可以让入侵者或得尽可能少的权限及数据,该文章已经发表在www.54nb.com,有兴趣的可以去看看。
注册会员,创建你的web开发资料库,新闻热点
疑难解答