数据库内核月报

数据库内核月报 - 2019 / 05

MSSQL · 最佳实践 · 挑战云计算安全的存储过程

Author: 风移

摘要

在SQL Server安全系列专题月报分享中,往期我们已经陆续分享了:如何使用对称密钥实现SQL Server列加密技术使用非对称密钥实现SQL Server列加密使用混合密钥实现SQL Server列加密技术列加密技术带来的查询性能问题以及相应解决方案行级别安全解决方案SQL Server 2016 dynamic data masking实现隐私数据列打码技术使用证书做数据库备份加密SQL Server Always Encrypted使用SSL加密连接这九篇文章,直接点击以上文章链接前往查看详情。本期月报我们分享SQL Server数据中,挑战云计算安全的几个存储过程。

问题引入

在SQL Server数据库中,存在三种类型的存储过程:系统存储过程,用户定义存储过程和扩展存储过程。系统存储过程是SQL Server服务安装时在系统中创建的,以“sp_”打头;用户自定义存储过程是指用户编写的存储过程;扩展存储过程是 SQL Server服务可以动态加载和运行的 DLL,可直接在SQL Server 实例的地址空间中运行。做为云计算厂商,SQL Server数据库中内置的这些非常好用的扩展存储过程,也给数据库PaaS平台安全提出了新的挑战。因此,我们有必要深入分析这些存在安全风险的扩展存储过程和对应方案,它们涉及的面非常广泛,包括:

 命令执行:在SQL Server中执行Windows命令

 注册表操作:在SQL Server中操作注册表

 OLE相关:在SQL Server中执行OLE相关动作

 文件相关:在SQL Server中操作文件相关

命令执行

执行命令的扩展存储过程,可以用来执行Windows操作系统的任何命令,只要在cmd里面能够做到的事情,都可以用它来执行。对,没错,它就是号称最最最为危险的存储过程xp_cmdshell,让我们来看看它的破坏力有多强。

开启xp_cmdshell

在使用xp_cmdshell执行命令之前,请使用sys.sp_configure系统存储过程来启用它,如下所示:

USE master  
GO  
EXEC sys.sp_configure 'show advanced options', 1  
RECONFIGURE WITH OVERRIDE
GO  

EXEC sys.sp_configure 'xp_cmdshell', 1  
RECONFIGURE WITH OVERRIDE  

GO  
EXEC sp_configure 'show advanced options', 0  
GO

查看主机IP

我们可以使用xp_cmdshell来查看SQL Server所在的主机IP,轻松拿到主机IP地址。

EXEC master.sys.xp_cmdshell 'ipconfig'

如下图所示:

01.png

创建文件夹

还可以创建文件,文件夹,查看文件夹中的内容,主机上文件暴露无遗。

EXEC master.sys.xp_cmdshell 'mkdir C:\tempfolder'
EXEC master.sys.xp_cmdshell 'dir C:\tempfolder'

如下所示:

02.png

创建用户

更要命的是,我们还可以创建用户,比如创建用户IAmTestUser,

-- create user IAmTestUser
EXEC master.sys.xp_cmdshell 'net user IAmTestUser IAmTestUser@1 /add', no_output
GO
-- query users
EXEC master.sys.xp_cmdshell 'net user'
GO

如下图所示:

03.png

添加到Administrator组

加到local Administrator组,然后想干什么就干什么了,如下:

-- add user IAmTestUser into local administrators group
EXEC master.sys.xp_cmdshell 'net localgroup administrators IAmTestUser /add', no_output
GO

删除用户

当然,还可以删除用户,影响正常用户活动。

-- remove the testing user
EXEC master.sys.xp_cmdshell 'net user IAmTestUser /delete', no_output
GO

禁用xp_cmdshell

以上仅仅是几个小演示,这个扩展存储过程非常危险,给数据库安全带来了极大挑战,所以,测试完毕后,必须关闭。

USE master  
GO  
EXEC sys.sp_configure 'show advanced options', 1  
RECONFIGURE WITH OVERRIDE
GO  
 
EXEC sys.sp_configure 'xp_cmdshell', 0  
RECONFIGURE WITH OVERRIDE  

GO  
EXEC sp_configure 'show advanced options', 0  
GO

从这几个简单的演示,我们可以体会到xp_cmdshell的破坏威力之大,因此,作为SQL Server云计算服务提供者,这个扩展存储过程是绝对不允许开放给用户使用的。

注册表操作

Windows注册表(Registry)是Microsoft Windows系统中的一个非常重要的数据库,它用于存储Windows系统本身和应用程序的设置信息。Windows注册表的本身的安全至关重要的,而SQL Server中一些内置的可操作注册表的扩展存储过程,给注册表的安全保护,提出了挑战,包括:

 xp_regwrite:写入注册表键值

 xp_regdeletevalue:删除注册表中的值

 xp_regdeletekey:删除注册表中的键

 xp_regread:读取注册表中的值

xp_regwrite

这个扩展存储过程可以写入注册表指定的键里指定的值。假如,我们需要在键HKEY_LOCAL_MACHINE\SOFTWARE\aaaKey\aaaValueName中写入值aaaValue,请使用如下方法:

EXEC master.sys.xp_regwrite
	@rootkey='HKEY_LOCAL_MACHINE',
	@key='SOFTWARE\aaaKey',
	@value_name='aaaValueName',
	@type='REG_SZ',
	@value='aaaValue'
;

结果展示如下:

04.png

xp_regdeletevalue

这个扩展存储过程可以用来删除注册表中指定的键中指定的值。比如把我们刚才创建的键值HKEY_LOCAL_MACHINE\SOFTWARE\aaaKey\aaaValueName中的Value删除掉。方法如下:

EXEC master.sys.xp_regdeletevalue
	@rootkey='HKEY_LOCAL_MACHINE',
	@key='SOFTWARE\aaaKey',
	@value_name='aaaValueName'
;

xp_regdeletekey

这个扩展存储过程可以删除注册表中指定的键,请小心谨慎使用。比如,删除我们刚才建立的测试注册表键HKEY_LOCAL_MACHINE\SOFTWARE\aaaKey。方法如下:

EXEC master.sys.xp_regdeletekey
	@rootkey='HKEY_LOCAL_MACHINE', 
	@key='SOFTWARE\aaaKey'
;

xp_regread

这个扩展存储过程可以读取注册表指定的键中指定的值,获取一些重要的敏感信息。比如,如下实例是获取SQL Server服务所在主机的主机名。

DECLARE 
	@hostName sysname
;
EXEC master.sys.xp_regread 
	@rootkey='HKEY_LOCAL_MACHINE', 
	@key='system\controlset001\control\computername\computername',
	@value_name='computername',
	@value=@hostName OUTPUT
;
SELECT 
	@hostName AS [host_name]
;

SQL Server中内置的关于注册表操作的扩展存储过程,也给我们的数据库系统安全,甚至是操作系统的安全带来了极大挑战。做为云厂商及云服务的提供者,必须严防死守,把好安全关。

OLE相关

与OLE相关的一系列存储过程:sp_OACreate,sp_OADestroy,sp_OAGetErrorInfo,sp_OAGetProperty,sp_OAMethod,sp_OASetProperty,sp_OAStop。这些存储过程和xp_cmdshell危险等级一样高。我们也必须严加防范。以下仅以sp_OACreate和sp_OAMethod配合使用为例说明。

启用OLE相关存储过程

要使用OLE相关存储过程,必须先启用对OLE存储过程的使用,方法如下:

USE master  
GO  
EXEC sys.sp_configure 'show advanced options', 1  
RECONFIGURE WITH OVERRIDE
GO  
 
EXEC sys.sp_configure 'Ole Automation Procedures', 1  
RECONFIGURE WITH OVERRIDE  

GO  
EXEC sp_configure 'show advanced options', 0  
GO

sp_OAmethod创建用户

使用OLE存储过程,创建Windows的用户。

DECLARE 
	@shell INT 
;
EXEC master.sys.sp_oacreate 
	'wscript.shell',
	@shell OUTPUT 
;

EXEC master.sys.sp_oamethod 
	@shell,
	'run',
	null,
	'C:\Windows\System32\cmd.exe /c net user IAmTestUser IAmTestUser@1 /add'
;

sp_OAmethod授权Admin

使用OLE存储过程,将刚才创建Windows的用户添加到local Administrator组中,便有了系统超级用户的所有权限。

DECLARE 
	@id INT 
;
EXEC master.sys.sp_oacreate 
	'wscript.shell',
	@id OUTPUT 
;

EXEC master.sys.sp_oamethod 
	@id,
	'run',
	null,
	'C:\Windows\System32\cmd.exe /c net localgroup administrators IAmTestUser /add'
;
GO

sp_OAmethod删除用户

当然,您可以删除用户。

DECLARE 
	@id INT 
;
EXEC master.sys.sp_oacreate 
	'wscript.shell',
	@id OUTPUT 
;

EXEC master.sys.sp_oamethod 
	@id,
	'run',
	null,
	'C:\Windows\System32\cmd.exe /c net user IAmTestUser /delete'
;
GO

禁用OLE相关存储过程

OLE存储过程测试完毕后,必须禁用掉,以免带来极大的安全风险。

USE master  
GO  
EXEC sys.sp_configure 'show advanced options', 1  
RECONFIGURE WITH OVERRIDE
GO  
 
EXEC sys.sp_configure 'Ole Automation Procedures', 1  
RECONFIGURE WITH OVERRIDE  

GO  
EXEC sp_configure 'show advanced options', 0  
GO

文件相关

SQL Server中除了可以执行windows command的扩展存储过程,操作注册表的扩展存储过程,以及OLE扩展存储过程,还有一类文件操作的存储过程,比如:

 xp_dirtree:查看文件目录结构

 xp_subdirs:查看子文件夹

 xp_fileexist:判断文件是否存储

 xp_delete_file:删除备份文件

xp_dirtree

这个扩展存储过程用来列出对应目录下所有文件和文件夹。

EXEC master.sys.xp_dirtree N'C:\tempfolder'

xp_subdirs

xp_subdirs用来显示给定的文件夹下的所有子文件夹。

EXEC master.sys.xp_subdirs N'C:\tempfolder'

xp_fileexist

确认某个文件是否存在。

EXEC master.sys.xp_fileexist 'C:\tempfolder\01\Deadlock_0_131700921198410000.xel'

xp_delete_file

这个扩展存储过程用于删除数据库备份文件,如下所示:

BACKUP DATABASE DDLCenter TO DISK = N'C:\tempfolder\01\DDLCenter.bak'
EXEC master.sys.xp_delete_file 0, 'C:\tempfolder\01\DDLCenter.bak',N'.bak'

应对方案

做为云计算厂商,为了保证SQL Server数据库平台的安全性,我们该如何应对这些高风险的扩展存储过程带给我们的安全挑战呢?我们的应对方案如下:

 禁用扩展存储过程

 删除扩展存储过程

 拒绝扩展存储过程执行权限

禁用扩展存储过程

有一些扩展存储过程属于是服务器外围配置选项,我们可以使用sys.sp_configure存储过程来开启和禁用它,这种方法在xp_cmdshell部分已经介绍过了,详情参见“开启xp_cmdshell”和“禁用xp_cmdshell”部分。

删除扩展存储过程

在SQL Server 2000及以前版本,我们还可以删除系统扩展存储过程,永绝后患。

EXEC master.sys.sp_dropextendedproc 'xp_cmdshell'

当然,删除后,你还是有后悔药可以再加回来

exec master.sys.sp_addextendedproc 'xp_cmdshell', 'C:\Program Files\Microsoft SQL Server\MSSQL\Binn\xplog70.dll'

而从SQL Server 2005开始,sys.sp_dropextendedproc不再支持对系统扩展存储过程的删除动作了,数据库管理员转而可以使用“拒绝扩展存储过程执行权限”的方式来达到相同的目的。

拒绝扩展存储过程执行权限

除了系统外围配置选项涉及的扩展存储过程可以通过sp_configure开启和禁用之外,剩下的系统扩展存储过程,我们只能通过拒绝PUBLIC角色可执行扩展存储过程权限的方式来禁用掉了,方法如下:

DENY EXECUTE ON sys.xp_regwrite TO PUBLIC;

此时,当用户再次执行写入注册表操作的时候,就会报告错误,比如:

EXEC master.sys.xp_regwrite
	@rootkey='HKEY_LOCAL_MACHINE',
	@key='SOFTWARE\aaaKey',
	@value_name='aaaValueName',
	@type='REG_SZ',
	@value='aaaValue'
;

错误信息如下所示:

05.png

这样从根本上达到了安全防范的目的,保护了云厂商SQL Server数据库PaaS平台的安全性。

检查扩展存储过程权限

最后,看看我们如何去查找某一个特定的系统扩展存储过程的权限呢?在此,以我们刚才拒绝执行权限的扩展存储过程xp_regwrite为例说明,如下:

SELECT 
	schema_name(obj.schema_id) AS [schema_name],
	obj.name AS [object_name],
	obj.type,
	b.permission_name,
	B.type,
	B.state_desc,
	C.name,
	c.type_desc    
FROM sys.all_objects AS obj WITH(NOLOCK)     
LEFT JOIN sys.database_permissions AS B  WITH(NOLOCK)
	ON B.major_id=obj.object_id AND B.minor_id=0 AND B.class=1      
LEFT JOIN sys.database_principals AS C  WITH(NOLOCK)
	ON C.principal_id = B.grantee_principal_id      
WHERE obj.name IN(SELECT object_name 
					FROM sys.system_components_surface_area_configuration AS x
					WHERE x.type = 'X' AND x.object_name = 'xp_regwrite')  
ORDER BY obj.name 

结果展示如下:

06.png

从检查的结果来看,PUBLIC角色已经被拒绝EXECUTE权限,达到了目的。

最后总结

本期月报我们分享了SQL Server数据库中几个有高安全风险的系统扩展存储过程,并没有完全罗列有安全风险的所有存储过程。保障云厂商SQL Server数据库PaaS平台的安全性,应对措施必不可少。