¡Hola, chicos!
En este artículo me gustaría compartir con ustedes una característica disponible desde SQL Server 2005, que le permite ejecutar código T-SQL en nombre de otro usuario. Estoy hablando del comando EJECUTAR COMO.

Con esta gran demanda de seguridad que buscan las empresas, impulsadas por las exigencias de adaptación al GDPR, las organizaciones muchas veces aprovechan para revisar todos los aspectos de seguridad, auditoría y monitoreo y este fue uno de los motivos que me motivó a escribir este artículo.

Si desea profundizar en más artículos sobre seguridad, asegúrese de haga clic en este enlace aquí para visitar mis otros artículos sobre este tema.

Si estás experimentando algún problema de seguridad o quieres consultoría especializada para analizar, probar y aplicar las mejores prácticas de seguridad en tu empresa, no dudes en contactarme. en este enlace aquí.

Para obtener más información sobre cómo utilizar EXECUTE AS para realizar un ataque de elevación de privilegios, lea el artículo SQL Server: ¡tenga cuidado con la función del servidor securityadmin! Usar la elevación de privilegios para convertirse en administrador de sistemas.

Introducción

De forma predeterminada, todas las operaciones durante una sesión están sujetas a comprobaciones de permisos para ese usuario. Cuando se ejecuta una instrucción EXECUTE AS, el contexto de ejecución de la sesión cambia al nombre de usuario o inicio de sesión específico. Después del cambio de contexto, los permisos se verifican en los tokens de seguridad y de inicio de sesión del usuario para la cuenta, en lugar de en la persona que llama a la instrucción EXECUTE AS.

Demostraré cómo funciona esto creando un usuario llamado “test”, con permiso db_datareader en la base de datos AdventureWorks, pero con lectura denegada en la tabla Person.Person:

USE [master]
GO

CREATE LOGIN [teste] WITH PASSWORD=N'aaa', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO

USE [AdventureWorks]
GO

CREATE USER [teste] FOR LOGIN [teste]
GO

ALTER ROLE [db_datareader] ADD MEMBER [teste]
GO

DENY SELECT ON Person.Person TO [teste]
GO

Después de ejecutar el script anterior, comprobaré qué usuario se encuentra actualmente en el contexto de mi sesión:

SELECT
    ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
    USER_NAME() AS [USER_NAME],
    SUSER_NAME() AS [SUSER_NAME],
    SUSER_SNAME() AS [SUSER_SNAME],
    SYSTEM_USER AS [SYSTEM_USER],
    IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]

Resultado:

Ahora, usaré la instrucción EXECUTE AS para cambiar el usuario actual en mi sesión:

EXECUTE AS USER = 'teste'
GO

SELECT
    ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
    USER_NAME() AS [USER_NAME],
    SUSER_NAME() AS [SUSER_NAME],
    SUSER_SNAME() AS [SUSER_SNAME],
    SYSTEM_USER AS [SYSTEM_USER],
    IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

Resultado:

Como este usuario tiene el rol de base de datos “db_datareader”, no debería tener ningún problema al intentar consultar datos de la tabla de direcciones, por ejemplo:

Pero si intentamos consultar datos de la tabla Persona, a la que le apliqué DENY SELECT a este usuario, no podrá ejecutar el comando. Vale recordar que mi usuario original es sysadmin, es decir, no tiene restricciones de acceso.

Con esto pude demostrar una forma muy interesante de uno de los propósitos de EXECUTE AS, que es validar si un usuario determinado puede realizar una actividad después de que el DBA conceda el permiso, Por ejemplo.

Tipos de personificaciones

Ver contenido
Hay algunas formas de ejecutar el comando EXECUTE AS, donde puede elegir los usuarios o inicios de sesión que serán suplantados por la instrucción. Describiré estos tipos a continuación en los 2 escenarios en los que se utiliza EXECUTE AS.

EJECUTAR COMO en consultas/declaraciones Ad-Hoc

  • ACCESO: Le permite suplantar un inicio de sesión de SQL Server, obteniendo todos los permisos a nivel de instancia, heredando permisos como CONTROL SERVER y roles de servidor como sysadmin y securityadmin, por ejemplo.
  • USUARIO: Permite hacerse pasar por un usuario de SQL Server, obteniendo todos los permisos a nivel de base de datos, heredando permisos como SELECT sobre una tabla y roles de base de datos, como db_datareader, por ejemplo.

Recordando que, incluso si te estás haciendo pasar por un usuario sysadmin a través de una base de datos que eres db_owner, por ejemplo, usando EXECUTE AS USER, no tendrás los “poderes” de sysadmin de ese usuario, ya que EXECUTE AS USER solo hereda permisos a nivel de base de datos. Como ya eres db_owner, no heredarás ningún permiso nuevo que no tengas ya, solo podrás ejecutar comandos como otro usuario (lo cual sigue siendo un riesgo). Si puede usar EJECUTAR COMO INICIAR SESIÓN de un usuario administrador de sistemas, entonces tendrá todos los "poderes" en el nivel de instancia que él tiene (es decir, puede hacer TODO).

EJECUTAR COMO en objetos de base de datos

  • LLAMADOR: Ejecutar como LLAMADOR es el valor predeterminado; Si no se especifican otras opciones, el procedimiento se ejecuta en el contexto de seguridad de la persona que llama.
  • DUEÑO: Ejecutar como PROPIETARIO ejecuta el procedimiento en el contexto del propietario del objeto. Si el objeto se crea en un esquema propiedad de dbo o del propietario de la base de datos, el procedimiento se ejecuta con permisos ilimitados.
  • SER: Ejecutar como SELF se ejecuta en el contexto de seguridad del creador del objeto. Esto equivale a ejecutar como usuario especificado, donde el usuario especificado es la persona que crea o cambia el objeto.
  • INICIO DE SESIÓN/USUARIO: Como ya se describió anteriormente, también puede usar un usuario específico o iniciar sesión en el encabezado del objeto, lo que permite que todos los que tengan permiso de EJECUCIÓN sobre este objeto, como un procedimiento almacenado, ejecuten este objeto con el contexto de ese usuario/inicio de sesión especificado automáticamente.

Más adelante hay un tema específico sobre EJECUTAR COMO en Objetos de Base de Datos, donde daré más detalles sobre este uso.

Revertir el EXECUTE AS y regresar al usuario original

Ver contenido
Después de ejecutar la instrucción EXECUTE AS para ejecutar comandos como otro usuario, a menudo desea volver a cambiar el contexto de seguridad de la sesión al usuario original. Una de las formas de hacerlo es crear una nueva sesión al volver a conectarse al banco.

El comando REVERTIR

La otra forma de hacerlo es utilizando el comando REVERT, que devolverá el contexto de seguridad al usuario anterior:

USE [dirceuresende]
GO

SELECT
    ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
    USER_NAME() AS [USER_NAME],
    SUSER_NAME() AS [SUSER_NAME],
    SUSER_SNAME() AS [SUSER_SNAME],
    SYSTEM_USER AS [SYSTEM_USER],
    IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
    
EXECUTE AS USER = 'teste_sysadmin'
GO

SELECT
    ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
    USER_NAME() AS [USER_NAME],
    SUSER_NAME() AS [SUSER_NAME],
    SUSER_SNAME() AS [SUSER_SNAME],
    SYSTEM_USER AS [SYSTEM_USER],
    IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

REVERT
GO

SELECT
    ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
    USER_NAME() AS [USER_NAME],
    SUSER_NAME() AS [SUSER_NAME],
    SUSER_SNAME() AS [SUSER_SNAME],
    SYSTEM_USER AS [SYSTEM_USER],
    IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

Resultado:

Vale la pena recordar que el comando EXECUTE AS se puede anidar, es decir, se puede crear un árbol de contextos de seguridad, como se muestra a continuación:

USE [master]
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO
    
EXECUTE AS LOGIN = 'teste_sysadmin'
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

EXECUTE AS LOGIN = 'teste'
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

EXECUTE AS LOGIN = 'teste2'
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

Resultado:

Y ahora, deshagamos la pila para mostrar el anidamiento de este contexto:

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

REVERT
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

REVERT
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

REVERT
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

Resultado:

CORRE COMO… CON COOKIES

Este parámetro especifica que el contexto de ejecución solo se puede revertir al contexto anterior si la instrucción REVERT FROM COOKIE que llama contiene el valor @varbinary_variable correcto. Esta es una medida de seguridad, utilizada especialmente en grupos de conexiones, para garantizar que solo aquellos que conocen el hash de la cookie puedan revertir el contexto de seguridad.

Ejemplo (eliminé los comandos GO para evitar perder información variable):

USE [master]
GO

-- Exibe as informações do usuário original
SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin];

-- Cria a variável do cookie e armazena o hash gerado
DECLARE @cookie VARBINARY(8000);
EXECUTE AS LOGIN = 'teste_sysadmin' WITH COOKIE INTO @cookie;

-- Exibe o cookie
SELECT @cookie;

-- Mostra o usuário personificado (teste_sysadmin(
SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin];

-- Volta o contexto de segurança para o usuário original
REVERT WITH COOKIE = @cookie;

-- Exibe as informações do usuário original novamente
SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin];

Resultado:

Ahora intentaré aplicar el comando REVERT sin especificar el token:

Ahora intentaré intercambiar el token e intentaré aplicar el comando REVERT:

EJECUTAR COMO... SIN REVERSIÓN

Después de presentar los comandos REVERT y REVERT FROM COOKIES, hay otra cláusula que significa que la suplantación no se puede revertir al usuario original en esta sesión. Esta declaración NO TIENE REVERSIÓN. En este caso, la única forma de revertir es abrir una nueva sesión.

Cuando se especifica la cláusula CON NO REVERT COOKIE = @varbinary_variable, el motor de base de datos de SQL Server pasa el valor de la cookie a @varbinary_variable. El contexto de ejecución establecido por esta declaración solo se puede revertir al contexto anterior si la declaración de llamada REVERT FROM COOKIE = @varbinary_variable tiene el mismo valor @varbinary_variable.

Esta opción es útil en un entorno donde se utiliza la agrupación de conexiones. La agrupación de conexiones es el mantenimiento de un grupo de conexiones de bases de datos para su reutilización por aplicaciones en un servidor de aplicaciones. Debido a que el valor pasado a @varbinary_variable solo lo conoce la persona que llama a la instrucción EXECUTE AS (en este caso, la aplicación), la persona que llama puede asegurarse de que nadie más pueda cambiar el contexto de ejecución establecido.

Ejemplo:

USE [master]
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO
    
EXECUTE AS LOGIN = 'teste_sysadmin' WITH NO REVERT
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

REVERT
GO

SELECT ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], USER_NAME() AS [USER_NAME], SUSER_NAME() AS [SUSER_NAME], SUSER_SNAME() AS [SUSER_SNAME], SYSTEM_USER AS [SYSTEM_USER], IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]
GO

Resultado:

¿Cuáles son los permisos para utilizar EXECUTE AS?

Ver contenido
Para poder utilizar el comando EXECUTE AS en cualquier inicio de sesión anterior a SQL Server 2014, necesitaba tener permiso de SERVIDOR DE CONTROL o ser parte de las funciones del servidor sysadmin o securityadmin. A partir de SQL Server 2014, esto terminó volviéndose más objetivo con el permiso IMPERSONATE ANY LOGIN, que es exclusivo para este tipo de actividad y no requiere que la persona tenga el rol de SERVIDOR DE CONTROL ni sea un usuario administrador de sistemas.

Sin embargo, usted que es DBA debe tener en cuenta que este permiso es EXTREMADAMENTE peligroso para un usuario común, ya que puede usar EXECUTE AS para ejecutar comandos usando el inicio de sesión de un usuario sysadmin, por ejemplo, y así hacer cualquier cosa en la instancia.

Esta fue una de las razones por las que se creó el permiso IMPERSONATE ANY LOGIN en SQL Server 2014. Los usuarios con permiso CONTROL SERVER ya tenían este privilegio implícitamente y con esto podían usar EXECUTE AS para ejecutar comandos como otro usuario, incluidos los usuarios sysadmin. A partir de SQL Server 2014, el DBA ahora puede aplicar un comando DENY IMPERSONATE ANY LOGIN a los usuarios con permiso CONTROL SERVER y evitar que esto suceda.

Vale la pena mencionar que también existe el comando GRANT IMPERSONATE ON LOGIN/USER::[usuario1] TO [usuario2], que le permite otorgar acceso IMPERSONATE a usuarios específicos. Además, los miembros del rol de base de datos db_owner pueden usar EXECUTE AS en usuarios creados en estas bases de datos. Recordando que, incluso si te estás haciendo pasar por un usuario sysadmin a través de una base de datos de la que eres db_owner, por ejemplo, usando EXECUTE AS USER, no tendrás los “poderes” de sysadmin de ese usuario, ya que EXECUTE AS User solo hereda permisos a nivel de base de datos. Como ya eres db_owner, no heredarás ningún permiso nuevo que no tengas ya, solo podrás ejecutar comandos como otro usuario (lo cual sigue siendo un riesgo).

Permisos explícitos para utilizar IMPERSONATE

Como mencioné anteriormente, existen algunas condiciones para usar el comando EXECUTE AS en SQL Server.

Condición n.º 1: SUplantar cualquier inicio de sesión

Los usuarios que tienen permiso explícito IMPERSONATE ANY LOGIN pueden ejecutar comandos como cualquier inicio de sesión en la instancia de SQL Server. Recuerde que los permisos son a nivel de instancia, es decir, se aplican a todas las bases de datos de esa instancia y los comandos que requieren privilegios como sysadmin y CONTROL SERVER se pueden utilizar a través de EXECUTE AS LOGIN.

Para liberar este permiso, debe utilizar el siguiente comando:

GRANT IMPERSONATE ANY LOGIN TO [login];

Condición #2: INICIAR SESIÓN SUPERSONADA

Los usuarios que tienen el permiso IMPERSONATE LOGIN pueden ejecutar comandos como inicios de sesión específicos en la instancia de SQL Server. Este comando permite a loginA ejecutar comandos como si fuera loginB y debe liberarse para cada inicio de sesión deseado. Recuerde que los permisos son a nivel de instancia, es decir, se aplican a todas las bases de datos de esa instancia y los comandos que requieren privilegios como sysadmin y CONTROL SERVER se pueden utilizar a través de EXECUTE AS LOGIN.

Para liberar este permiso, debe utilizar el siguiente comando:

GRANT IMPERSONATE ON LOGIN::LoginB TO [LoginA];

Condición #3: USUARIO SUFICIENTE

Los usuarios que tienen el permiso USUARIO IMPERSONADO pueden ejecutar comandos como usuarios específicos en una base de datos. Este comando permite al usuario A ejecutar comandos como si fuera el usuario B en la base de datos, que tiene permiso IMPERSONATE y debe liberarse para cada inicio de sesión deseado. Los comandos que requieren permisos a nivel de instancia (por ejemplo: apagar, cambiar miembros de la función del servidor, crear un servidor vinculado, etc.) NO son ejecutados por USUARIO IMPERSONADO, solo los comandos que requieren permisos a nivel de base de datos, como INSERTAR, ACTUALIZAR, ELIMINAR, etc.

Para liberar este permiso, debe utilizar el siguiente comando:

GRANT IMPERSONATE ON USER::UsuarioB TO [UsuarioA];

Permisos implícitos para utilizar IMPERSONATE

Ahora demostraré que existen algunas condiciones implícitas en las que puede utilizar el comando EXECUTE AS en SQL Server sin tener permiso explícito para hacerlo.

Condición #1: SYSADMIN

Rol de “Administrador” de SQL Server. Los usuarios en este rol pueden hacer cualquier cosa en la base de datos y, por lo tanto, ya tienen permisos IMPERSONATE LOGIN, IMPERSONATE USER y IMPERSONATE CUALQUIER LOGIN y no se les pueden negar privilegios con DENEGAR.

Para agregar a alguien a este rol, use el siguiente comando:

ALTER SERVER ROLE [sysadmin] ADD MEMBER [Login];

Condición #2: SERVIDOR DE CONTROL

Permiso de “Administrador” de SQL Server. Los usuarios que tienen este permiso pueden hacer casi cualquier cosa en la base de datos y, por lo tanto, ya tienen los permisos INICIO DE SESIÓN IMPERSONADO, USUARIO IMPERSONADO y IMPERSONAR CUALQUIER INICIO DE SESIÓN, pero, a diferencia del rol de administrador de sistemas, a estos usuarios se les PUEDEN negar los privilegios IMPERSONAR con DENEGAR.

Para agregar a alguien a este rol, use el siguiente comando:

GRANT CONTROL SERVER TO [Login];

Condición #3: ADMINISTRADOR DE SEGURIDAD

Los usuarios que tienen la función de servidor securityadmin controlan la seguridad y los permisos de la instancia de SQL Server. Al estar en este rol, estos usuarios tienen el permiso IMPERSONATE ANY LOGIN y, por lo tanto, pueden hacer cualquier cosa en la base de datos, ya que pueden usar el comando EXECUTE AS LOGIN y ejecutar comandos como si fueran un usuario administrador de sistemas y, por esta razón, la propia documentación de Microsoft trata este rol como equivalente al rol de administrador de sistemas en términos de seguridad. A diferencia del rol de administrador de sistemas, a estos usuarios se les PUEDEN negar privilegios IMPERSONATE con DENEGAR.

Para agregar a alguien a este rol, use el siguiente comando:

ALTER SERVER ROLE [securityadmin] ADD MEMBER [Login];

Condición #4: db_owner

Los usuarios que tienen el rol de base de datos db_owner pueden ejecutar cualquier comando DDL, DCL o DML en la base de datos en la que tienen este rol. Por esta razón, estos usuarios ya tienen el permiso IMPERSONATE USER implícito en todos los usuarios de la base de datos. Vale la pena recordar que a estos usuarios se les PUEDEN negar privilegios IMPERSONATE con DENEGAR.

Para agregar a alguien a este rol, use el siguiente comando:

ALTER DATABASE ROLE [db_owner] ADD MEMBER [Usuario];

Condición #5: db_securityadmin

Los usuarios que tienen el rol de base de datos db_securityadmin pueden administrar la seguridad y los permisos en la base de datos. Por esta razón, estos usuarios tienen el permiso IMPERSONATE USER implícito en todos los usuarios de la base de datos, pudiendo ejecutar comandos como si fueran siquiera uno más de los usuarios en el rol db_owner. Vale la pena recordar que a estos usuarios se les PUEDEN negar privilegios IMPERSONATE con DENEGAR.

Para agregar a alguien a este rol, use el siguiente comando:

ALTER DATABASE ROLE [db_securityadmin] ADD MEMBER [Usuario];

¿Quién tiene permiso para ejecutar EXECUTE AS?

Ver contenido
Como ya mencioné, para poder utilizar el comando EXECUTE AS en cualquier inicio de sesión, debe tener el permiso CONTROL SERVER, ser parte de los roles de servidor sysadmin o securityadmin o tener el privilegio explícito IMPERSONATE ANY LOGIN. Si el usuario tiene permiso IMPERSONATE, puede usar EXECUTE AS solo en usuarios específicos para quienes tiene este permiso.

Hablando a nivel de base de datos, donde el usuario puede realizar IMPERSONATE en los usuarios de la base de datos, deberá tener el rol de base de datos db_owner o tener el permiso IMPERSONATE ON USER para los usuarios específicos que puede suplantar.

Por lo tanto, demostraré a continuación cómo identificar quiénes son los usuarios que tienen estos permisos en su instancia de SQL Server.

Usuarios con permisos de SERVIDOR DE CONTROL o roles de administrador de sistemas y administrador de seguridad

Para identificar a los usuarios con permisos o roles de SERVIDOR DE CONTROL sysadmin y securityadmin, que pueden ejecutar EXECUTE AS para cualquier inicio de sesión, ejecute el siguiente script:

-- Verificando usuários com permissões CONTROL SERVER ou roles sysadmin e securityadmin
SELECT 
    A.[name] AS [login],
    A.principal_id,
    A.[sid],
    A.[type_desc],
    A.is_disabled,
    B.[permission_name]
FROM
    sys.server_principals A
    JOIN (
        SELECT 
            grantee_principal_id,
            [permission_name] COLLATE SQL_Latin1_General_CP1_CI_AI AS [permission_name]
        FROM 
            sys.server_permissions
        WHERE 
            class_desc = 'SERVER' 
            AND [permission_name] = 'CONTROL SERVER' 
            AND [state] IN ('G', 'W')

        UNION

        SELECT 
            a1.member_principal_id,
            a2.[name] COLLATE SQL_Latin1_General_CP1_CI_AI AS [role]
        FROM 
            sys.server_role_members AS a1
            JOIN sys.server_principals AS a2 ON a1.role_principal_id = a2.principal_id 
        WHERE 
            a2.[name] IN ('sysadmin', 'securityadmin')
    ) B ON A.principal_id = B.grantee_principal_id
WHERE
    A.is_fixed_role = 0

Resultado:

Usuarios con IMPERSONAR CUALQUIER INICIO DE SESIÓN

Para identificar qué usuarios tienen el permiso explícito IMPERSONAR CUALQUIER INICIO DE SESIÓN y, por lo tanto, pueden ejecutar comandos como cualquier usuario, ejecute el siguiente script:

-- Verificando usuários com IMPERSONATE ANY LOGIN
SELECT 
    A.class,
    A.class_desc,
    A.[type],
    A.[permission_name],
    A.[state],
    A.state_desc,
    B.[name] AS grantee, -- quem recebeu a permissão
    C.[name] AS grantor -- quem concedeu a permissão
FROM 
    sys.server_permissions A
    JOIN sys.server_principals B ON A.grantee_principal_id = B.principal_id
    LEFT JOIN sys.server_principals C ON A.grantor_principal_id = C.principal_id
WHERE
    A.[type] = 'IAL'

Resultado:

Usuarios con inicio de sesión suplantado

Para identificar qué usuarios tienen permiso explícito de INICIAR SESIÓN IMPERSONADA y pueden ejecutar comandos como algunos usuarios específicos, ejecute el siguiente script:

-- Verificando usuários com IMPERSONATE LOGIN
SELECT 
    A.class,
    A.class_desc,
    A.[type],
    A.[permission_name],
    A.[state],
    A.state_desc,
    B.[name] AS grantee, -- quem recebeu a permissão
    C.[name] AS impersonated_user -- quem pode ser personificado por quem recebeu a permissão
FROM 
    sys.server_permissions A
    JOIN sys.server_principals B ON A.grantee_principal_id = B.principal_id
    LEFT JOIN sys.server_principals C ON A.grantor_principal_id = C.principal_id
WHERE
    A.[type] = 'IM'

Resultado:

Usuarios en los roles de base de datos db_owner o db_securityadmin

Para identificar quiénes son los usuarios que están en los roles de base de datos db_owner o db_securityadmin y pueden ejecutar comandos como cualquier usuario de base de datos, ejecute el siguiente script:

-- Verificando usuários na role db_owner ou db_securityadmin
SELECT 
    DB_NAME() AS [database],
    B.[name] AS [user],
    C.[name] AS [database_role]
FROM
    sys.database_role_members A
    JOIN sys.database_principals B ON A.member_principal_id = B.principal_id
    JOIN sys.database_principals C ON A.role_principal_id = C.principal_id
WHERE
    C.[name] IN ('db_owner', 'db_securityadmin')
    AND B.[name] <> 'dbo'

Resultado:

Usuarios en los roles db_owner y db_securityadmin (verifica todas las bases de datos)

Como en el ejemplo anterior, para identificar quiénes son los usuarios que están en los roles de base de datos db_owner o db_securityadmin, analizando ahora todas las bases de datos de la instancia, ejecute el siguiente script:

-- Verificando usuários nas roles db_owner e db_securityadmin em todos os databases
IF (OBJECT_ID('tempdb..#Dbowner_Database') IS NOT NULL) DROP TABLE #Dbowner_Database
CREATE TABLE #Dbowner_Database ( [database] nvarchar(128), [user] nvarchar(128), [database_role] nvarchar(128) )

INSERT INTO #Dbowner_Database
EXEC sys.sp_MSforeachdb '
SELECT 
    ''?'' AS [database],
    B.[name] AS [user],
    C.[name] AS [database_role]
FROM
    [?].sys.database_role_members A
    JOIN [?].sys.database_principals B ON A.member_principal_id = B.principal_id
    JOIN [?].sys.database_principals C ON A.role_principal_id = C.principal_id
WHERE
    C.[name] IN (''db_owner'', ''db_securityadmin'')
    AND B.[name] <> ''dbo'''


SELECT * FROM #Dbowner_Database

Resultado:

Usuarios con USUARIO IMPERSONADO en una base de datos

Para identificar a los usuarios que tienen permiso explícito de USUARIO IMPERSONADO y pueden ejecutar comandos como algunos usuarios de bases de datos específicos, ejecute el siguiente script:

-- Verificando usuários com IMPERSONATE USER em um database
SELECT 
    A.class,
    A.class_desc,
    A.[type],
    A.[permission_name],
    A.[state],
    A.state_desc,
    B.[name] AS grantee, -- quem recebeu a permissão
    C.[name] AS impersonated_user -- quem pode ser personificado por quem recebeu a permissão
FROM
    sys.database_permissions A
    JOIN sys.database_principals B ON A.grantee_principal_id = B.principal_id
    LEFT JOIN sys.database_principals C ON A.grantor_principal_id = C.principal_id
WHERE
    A.[type] = 'IM'

Resultado:

Usuarios con USUARIO IMPERSONADO (comprueba todas las bases de datos)

Como en el ejemplo anterior, para identificar quiénes son los usuarios que están en los roles de base de datos sysadmin o db_securityadmin, ahora mirando todas las bases de datos de la instancia, ejecute el siguiente script:

-- Verificando usuários com IMPERSONATE USER em todos os databases
IF (OBJECT_ID('tempdb..#Permissoes') IS NOT NULL) DROP TABLE #Permissoes
CREATE TABLE #Permissoes ( [database] nvarchar(128), [class] tinyint, [class_desc] nvarchar(60), [type] char(4), [permission_name] nvarchar(128), [state] char(1), [state_desc] nvarchar(60), [grantee] nvarchar(128), [impersonated_user] nvarchar(128) )

INSERT INTO #Permissoes
EXEC sys.sp_MSforeachdb '
SELECT
    ''?'' as [database],
    A.class,
    A.class_desc,
    A.[type],
    A.[permission_name],
    A.[state],
    A.state_desc,
    B.[name] AS grantee,
    C.[name] AS impersonated_user
FROM
    [?].sys.database_permissions A
    JOIN [?].sys.database_principals B ON A.grantee_principal_id = B.principal_id
    LEFT JOIN [?].sys.database_principals C ON A.grantor_principal_id = C.principal_id
WHERE
    A.[type] = ''IM'''


SELECT * FROM #Permissoes

Resultado:

EJECUTAR COMO en objetos de base de datos

Ver contenido
Una práctica muy común en el uso de EXECUTE AS es su uso en objetos de bases de datos, como procedimientos almacenados, para definir el permiso predeterminado para que se ejecuten estos objetos. En otras palabras, puede crear un Procedimiento Almacenado que siempre se ejecutará como el usuario “dirceu.resende”, que es miembro del rol del servidor sysadmin y por lo tanto tiene permiso para hacer cualquier cosa, y cualquiera que tenga acceso de EJECUCIÓN a este Procedimiento Almacenado puede ejecutarlo, sin necesidad de tener el privilegio de SUplantar cualquier inicio de sesión y/o tener acceso a las actividades que realiza este Procedimiento Almacenado.

Antes de los ejemplos, les recordaré las posibles formas de EJECUTAR COMO en objetos:

  • LLAMADOR: Ejecutar como LLAMADOR es el valor predeterminado; Si no se especifican otras opciones, el procedimiento se ejecuta en el contexto de seguridad de la persona que llama.
  • DUEÑO: Ejecutar como PROPIETARIO ejecuta el procedimiento en el contexto del propietario del objeto. Si el objeto se crea en un esquema propiedad de dbo o del propietario de la base de datos, el procedimiento se ejecuta con permisos ilimitados.
  • SER: Ejecutar como SELF se ejecuta en el contexto de seguridad del creador del objeto. Esto equivale a ejecutar como usuario especificado, donde el usuario especificado es la persona que crea o cambia el objeto.
  • INICIO DE SESIÓN/USUARIO: Como ya se describió anteriormente, también puede usar un usuario específico (permisos a nivel de base de datos) o iniciar sesión (permisos a nivel de instancia) en el encabezado del objeto, lo que permite a todos los que tienen permiso EJECUTAR sobre este objeto, como un procedimiento almacenado, ejecutar este objeto con el contexto de ese usuario/inicio de sesión especificado automáticamente.

Los tipos de objetos que pueden tener la cláusula EXECUTE AS en la definición son:

  • Procedimientos almacenados – LLAMADOR | YO | PROPIETARIO | 'nombre de usuario'
  • Funciones (excepto funciones con valores de tabla en línea) – CALLER | YO | 'nombre de usuario'
  • Activadores DDL con alcance de base de datos – LLAMADOR | YO | 'nombre de usuario'
  • Activadores DDL con alcance del servidor y activadores de inicio de sesión – LLAMADOR | YO | 'nombre_inicio de sesión'
  • Colas – AUTO | PROPIETARIO | 'nombre de usuario'
  • Base de datos SQL de Azure – Procedimientos almacenados – LLAMADOR | YO | PROPIETARIO | 'nombre de usuario'
  • Base de datos SQL de Azure: funciones (excepto funciones con valores de tabla en línea) – LLAMADOR | YO | PROPIETARIO | 'nombre de usuario'
  • Base de datos SQL de Azure: desencadenadores DDL con alcance de base de datos: LLAMADOR | YO | 'nombre de usuario'

Para demostrar un uso común de EXECUTE AS en procedimientos almacenados, crearé un SP en msdb para ejecutar trabajos pasando el nombre del trabajo como parámetro:

USE [msdb]
GO

CREATE OR ALTER PROCEDURE dbo.stpInicia_Job (
    @Job_Name AS VARCHAR(128)
)
WITH EXECUTE AS OWNER
AS 
BEGIN
    
    EXEC msdb.dbo.sp_start_job
        @job_name = @Job_Name

END
GO

GRANT EXECUTE ON dbo.stpInicia_Job TO [teste]
GO

Ahora intentaré ejecutar sp_start_job manualmente:

y luego intente ejecutarlo a través de este SP que creé:

Al agregar una cláusula EXECUTE AS a un objeto, no necesita hacer nada para que el usuario tenga acceso a este SP, además del permiso EXECUTE habitual en este procedimiento almacenado, por ejemplo. Repetiré los ejemplos conectados directamente con el usuario “test”, sin utilizar EXECUTE AS en ningún momento:

Y ahora voy a ejecutar el Procedimiento que creé y que me permitirá ejecutar cualquier trabajo en la instancia, incluso sin tener permisos para hacerlo en mi usuario:

Nota: Este SP stpInicia_Job DEBE crearse en msdb debido a la forma en que funcionan los permisos en SQL Server. Si creas un Procedimiento Almacenado y dentro de él hay consultas o comandos sobre objetos de otras bases de datos, el usuario ejecutante tendrá que tener permisos explícitos sobre estos objetos, incluso usando EXECUTE AS. Si todo lo que hay dentro del Procedimiento almacenado solo hace referencia a objetos de la propia base de datos, el ejecutor no necesita tener ningún permiso sobre los objetos involucrados dentro del SP, solo permiso de EJECUCIÓN en el propio Procedimiento almacenado.

Vale la pena recordar que cuando crea un objeto con EXECUTE AS USER = 'Usuario', desactivar o negar el privilegio de conexión para el inicio de sesión asociado con ese usuario NO cambiará el comportamiento de uso de ese objeto, ya que las acciones de inicio de sesión no terminan influyendo en los permisos a nivel de la base de datos en esta situación (excepto en los casos en que el usuario es un administrador de sistemas, por ejemplo, y no tiene permisos explícitos en la base de datos para ese objeto).

En otras palabras, si un SP tiene la cláusula CON EXECUTE AS USER = 'Usuario1' y usted desactiva el inicio de sesión asociado con ese usuario, esto no hará que un SP que se haya ejecutado genere un error cuando alguien intente ejecutarlo. Pero si cambia el nombre o elimina a este usuario en la base de datos, SP dejará de funcionar.

Pruebas de seguridad en rutinas de auditoría

Ver contenido

Prueba n.º 1: hacerse pasar por cualquier inicio de sesión

Para probar la suplantación utilizada incorrectamente, tomaré el mismo usuario del ejemplo (prueba) y le otorgaré el privilegio IMPERSONATE ANY LOGIN.

USE [master]
GO

GRANT IMPERSONATE ANY LOGIN TO [teste]
GO

Y ahora me voy a conectar a la instancia con este usuario:

E intentemos realizar la selección en la tabla Persona, a la que le apliqué un DENY SELECT a este usuario:

Bueno, realmente no tiene permiso. ¿Qué pasa si utilizamos otro usuario para acceder a los datos? Por ejemplo, el usuario “dirceu.resende”, que es sysadmin.

¿Revisemos a qué permisos tiene acceso después de suplantar?

SELECT
    ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN],
    USER_NAME() AS [USER_NAME],
    SUSER_NAME() AS [SUSER_NAME],
    SUSER_SNAME() AS [SUSER_SNAME],
    SYSTEM_USER AS [SYSTEM_USER],
    IS_SRVROLEMEMBER('sysadmin') AS [isSysAdmin]

SELECT 'login' AS token_type, * 
FROM sys.login_token AS LT

UNION ALL

SELECT 'user' AS token_type, * 
FROM sys.user_token AS UT
GO

EXECUTE AS LOGIN = 'dirceu.resende'
GO

SELECT 'login' AS token_type, * 
FROM sys.login_token AS LT

UNION ALL

SELECT 'user' AS token_type, * 
FROM sys.user_token AS UT

Resultado:

Hmm... ¿Qué pasaría si intentáramos crear un cambio en una tabla? Este usuario de "prueba" solo tiene el permiso db_datareader.

Sí... Este usuario puede hacer todo lo que el usuario suplantado puede hacer. Como me estoy haciendo pasar por un usuario que es miembro del rol de administrador de sistemas del servidor, un usuario normal ahora puede hacer CUALQUIER COSA, ¡incluso apagar el servidor! ¿Y quiere seguir siendo un usuario “corriente”?

¡Listo! Ahora él mismo se ha convertido en administrador de sistemas. Si lo desea, puede incluso eliminar otros usuarios administradores de sistemas y "tomar" el control de la instancia usted mismo. ¡Mira cómo este permiso puede ser extremadamente peligroso!

Y la cosa no termina ahí... Mire otro ejemplo de cómo este permiso, cuando se usa incorrectamente, puede causar un gran daño. Imagine que usted, DBA, tiene una rutina para registrar los cambios realizados en su base de datos, como la que pongo a disposición en la publicación. Cómo crear un activador de auditoría para registrar la manipulación de objetos en SQL Server.

Ahora, ¿imagina a un usuario malintencionado usando esto para hacer cosas incorrectas y culpar a otro colega? Probémoslo... Primero, crearé la tabla y cambiaré una columna. Todos los registros se registrarán utilizando el usuario que realizó las acciones.

Y ahora, para borrar la tabla, usaré EXECUTE AS para borrarla como si fuera un usuario más.

Listo. Me equivoqué e incluso le eché la culpa a mi colega. ¿Quieres resolver esto? Comience a utilizar la función ORIGINAL_LOGIN() en sus rutinas de auditoría y registro. Para demostrar esto, cambiaré el disparador que creé para crear esta auditoría:

Ahora, crearé una tabla nuevamente, la cambiaré y suplantaré el login “dirceu.resende” para eliminar la tabla y dejar las responsabilidades en sus cuentas:

Sí, esta vez no funcionó... La función ORIGINAL_LOGIN() reveló el verdadero ejecutor de los comandos, incluso con EXECUTE AS.

Prueba n.º 2: prueba con USUARIO SUPERSONADO

Otra prueba que podemos intentar es liberar el privilegio de suplantación de identidad de un usuario específico. Por ejemplo, quiero que el usuario "prueba" pueda utilizar el comando EJECUTAR AS igual que el usuario "prueba2", ambos con un nivel de acceso bajo. Para ello crearé el usuario “teste2”, con los mismos permisos que “teste”, pero sin el DENY de select en la tabla Persona.

USE [master]
GO

CREATE LOGIN [teste2] WITH PASSWORD=N'aaa', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO

USE [AdventureWorks]
GO

CREATE USER [teste2] FOR LOGIN [teste2]
GO

ALTER ROLE [db_datareader] ADD MEMBER [teste2]
GO

Usuario creado, intentemos usar EXECUTE AS del usuario “de prueba”:

Evidentemente hubo un error. El usuario de “prueba” no tiene permiso SUPERSONAR. Otorguemos permiso e intentemos nuevamente:

USE [master]
GO

GRANT IMPERSONATE ON LOGIN::teste2 TO [teste]
GO

Probemos si funcionó:

¡Ups! Ahora estoy ejecutando los comandos como si fuera el usuario “teste2”. El usuario de “prueba” no puede consultar la tabla Persona, ya que tiene DENY SELECT allí. Intentemos leer los datos a través del usuario “teste2” con EXECUTE AS:

¡Ups! Pudimos leer los datos de la tabla, aunque el usuario de "prueba" no tenía permiso para hacerlo. Confirmemos si realmente no puede:

Sí... Realmente no es posible, sólo con EXECUTE AS... ¿Y puedo usar EXECUTE AS en otro usuario al que no tengo acceso?

¡Preguntarse! No pude aplicar IMPERSONATE a otro usuario, especialmente a “dirceu.resende”, que es sysadmin. Imagínese el daño que podría causar.

RUN AS y gobernador de recursos

Ver contenido
Un punto importante que se debe considerar en la suplantación es cuando la instancia tiene un limitador de recursos para ciertos usuarios, lo cual se puede hacer usando el Gobernador de recursos en SQL Server.

Lo que quiero probar aquí es si EXECUTE AS también “engaña” al Gobernador de Recursos, logrando ejecutar una consulta sin estar limitado por el RG.

Para hacer esto, crearé el grupo de recursos, el grupo de cargas de trabajo, la función de clasificación y habilitaré el gobernador de recursos en la instancia, limitando los recursos que puede utilizar el usuario de "prueba":

USE [master]
GO

----------------------------------------------------------------------------------------------
-- "Limpeza" do Resource Governor
----------------------------------------------------------------------------------------------

ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=NULL)
GO

ALTER RESOURCE GOVERNOR RECONFIGURE
GO

ALTER RESOURCE GOVERNOR DISABLE
GO

IF (EXISTS(SELECT NULL FROM sys.resource_governor_workload_groups WHERE [name] = 'Grupo1')) DROP WORKLOAD GROUP [Grupo1] 
GO

IF (EXISTS(SELECT NULL FROM sys.dm_resource_governor_resource_pools WHERE [name] = 'PoolA')) DROP RESOURCE POOL [PoolA] 
GO

IF (OBJECT_ID('dbo.fncClassifica_ResourceGovernor') IS NOT NULL) DROP FUNCTION dbo.fncClassifica_ResourceGovernor
GO


----------------------------------------------------------------------------------------------
-- Criação do Pool de Recursos
----------------------------------------------------------------------------------------------

CREATE RESOURCE POOL [PoolA] 
WITH (
    MIN_CPU_PERCENT=0, 
    MAX_CPU_PERCENT=20, 
    CAP_CPU_PERCENT=20,
    MIN_MEMORY_PERCENT=0, 
    MAX_MEMORY_PERCENT=30, 
    AFFINITY SCHEDULER = AUTO, 
    MIN_IOPS_PER_VOLUME=0, 
    MAX_IOPS_PER_VOLUME=300
)
GO


----------------------------------------------------------------------------------------------
-- Criação do Workload Group
----------------------------------------------------------------------------------------------

CREATE WORKLOAD GROUP [Grupo1] 
WITH (
    GROUP_MAX_REQUESTS=0, 
    IMPORTANCE=LOW, 
    REQUEST_MAX_CPU_TIME_SEC=2, 
    REQUEST_MAX_MEMORY_GRANT_PERCENT=25, 
    REQUEST_MEMORY_GRANT_TIMEOUT_SEC=0, 
    MAX_DOP=1
) USING [PoolA]
GO


----------------------------------------------------------------------------------------------
-- Criação da função de classificação
----------------------------------------------------------------------------------------------

CREATE FUNCTION fncClassifica_ResourceGovernor() 
RETURNS SYSNAME 
WITH SCHEMABINDING 
AS 
BEGIN 
        
    DECLARE @grp_name AS SYSNAME, @Usuario VARCHAR(200) = SUSER_NAME(), @Programa VARCHAR(200) = APP_NAME()
    
    IF (@Usuario IN ('teste', 'teste2'))
        SET @grp_name = 'Grupo1'
    ELSE IF (@Programa LIKE '%Management Studio%')
        SET @grp_name = 'Grupo2'

    
    RETURN @grp_name 

END 
GO


----------------------------------------------------------------------------------------------
-- Habilita o Resource Governor, aplica a função de classificação e confirma as alterações
----------------------------------------------------------------------------------------------

ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=dbo.fncClassifica_ResourceGovernor)
GO

ALTER RESOURCE GOVERNOR RECONFIGURE
GO

Después de crear y activar el Gobernador de recursos, ejecutaré una consulta intensa para probar la limitación de recursos:

Mientras se ejecuta la consulta, miraré el Consulta para devolver consultas en ejecución (sp_WhoIsActive sin consumir TempDB) qué perfil se está utilizando para esta consulta:

Bueno entonces. La consulta que utilizó el usuario de "prueba" utilizó el grupo de carga de trabajo "Grupo" del regulador de recursos, que tiene limitaciones de IOPS, CPU y memoria, tal como lo configuré. Crearé el usuario "dirceu.resende" para el inicio de sesión del administrador del sistema "dirceu.resende" en la base de datos de AdventureWorks y liberaré el permiso IMPERSONATE de este usuario al usuario de "prueba":

-- Cria o usuário "dirceu.resende"
USE [AdventureWorks]
GO

CREATE USER [dirceu.resende] FOR LOGIN [dirceu.resende]
GO

-- Libera permissão de IMPERSONATE no usuário "dirceu.resende" para o usuário "teste"
GRANT IMPERSONATE ON USER::[dirceu.resende] TO [teste]
GO

-- Notem que mesmo o login "dirceu.resende" sendo sysadmin, preciso liberar a permissão de leitura para ele nos objetos envolvidos pro EXECUTE AS USER funcionar.
-- Se fosse EXECUTE AS LOGIN, não precisaria, pois iria receber os privilégios de um sysadmin
ALTER ROLE [db_datareader] ADD MEMBER [dirceu.resende]
GO

Ahora probemos el uso de EJECUTAR COMO USUARIO para un usuario que no tenga esta limitación, como por ejemplo el usuario “dirceu.resende”:

Como era de esperar, el Gobernador de Recursos no fue “engañado” por EJECUTAR COMO USUARIO y continuó limitando al usuario “de prueba” incluso disfrazado de “dirceu.resende”, ya que solo hereda “poderes” a nivel de base de datos y no a nivel de instancia. Ahora, ¿qué sucede si intento ejecutar EXECUTE AS LOGIN? ¡Vamos a probar!

GRANT IMPERSONATE ON LOGIN::[dirceu.resende] TO [teste]
GO

Y para mi sorpresa, a pesar de que recibí los “poderes” de un administrador de sistemas, Resource Governor continuó limitando los recursos del usuario “de prueba”, incluso usando EXECUTE AS LOGIN del usuario “dirceu.resende” (y sí, abrí una nueva sesión para probar):

Y ahora ejecutaré la consulta con el usuario “dirceu.resende”, sin usar suplantar, lo que nos mostrará que el Gobernador de Recursos ahora no está limitando los recursos de esta sesión (grupo predeterminado):

Referencias

¡Eso es todo, amigos!
¡Un abrazo grande y hasta luego!