¡Hablen, mis queridos lectores!
En este artículo, me gustaría ampliar un poco el tema de la seguridad y compartir con ustedes cómo desactivar el inicio de sesión “sa” minimizando los impactos. Como ya mencioné en el artículo. SQL Server: cómo activar/habilitar el usuario sa, es una buena práctica de seguridad mantener desactivado y renombrado al usuario “sa”, ya que este usuario tiene el rol sysadmin (no se puede eliminar), no se puede eliminar de la instancia y es un usuario estándar, es decir, está presente en cualquier instancia de SQL Server, lo que convierte a este usuario en el objetivo preferido de posibles atacantes. De hecho, esta es una de las características de seguridad del Revisión GRATUITA del servidor SQL que el Fabricio Lima se ofrece a conocer la empresa.

Durante unos días hice pública en la Web una instancia de SQL Server y Power BI Report Server para realizar algunas pruebas. Después de unos días, vi en el registro de errores de SQL Server que ya estaban intentando invadir mi base. ¿Imagínese qué usuario intentó utilizar más para acceder a mi banco?

¿Quieres comprobar cómo están estas estadísticas en tu instancia? Simplemente ejecute el siguiente script:

DECLARE @ArquivosLog TABLE ( LogNumber INT, StartDate DATETIME, SizeInBytes INT )
DECLARE @Dados TABLE ( [LogDate] datetime, [ProcessInfo] nvarchar(12), [Text] nvarchar(3999) )

INSERT INTO @ArquivosLog 
EXEC sys.xp_enumerrorlogs 1


DECLARE 
    @Contador INT = 0, 
    @Total INT = (SELECT COUNT(*) FROM @ArquivosLog)

WHILE(@Contador < @Total)
BEGIN

    INSERT INTO @Dados
    EXEC sys.sp_readerrorlog @Contador, 1, 'login failed'
    
    SET @Contador += 1

END


SELECT
   MIN(LogDate) AS Dt_Menor_Ocorrencia,
   MAX(LogDate) AS Dt_Maior_Ocorrencia,
   SUBSTRING([Text], 1, IIF(CHARINDEX('[', [Text]) = 0, LEN([Text]), CHARINDEX('[', [Text]) - 1))  AS Texto,
   COUNT(DISTINCT [Text]) AS Quantidade
FROM
   @Dados
GROUP BY
   SUBSTRING([Text], 1, IIF(CHARINDEX('[', [Text]) = 0, LEN([Text]), CHARINDEX('[', [Text]) - 1))
ORDER BY
   4 DESC

Ahora que he hecho un breve resumen de por qué se debe desactivar y cambiar el nombre de este usuario, explicaré cómo podemos hacer esto en su base de datos. En teoría, es algo sumamente sencillo:

USE [master]
GO

ALTER LOGIN [sa] DISABLE
GO

ALTER LOGIN [sa] WITH NAME = [sa_DESATIVADO]
GO 

O incluso, a través de la interfaz de Management Studio (SSMS):

El problema es que muchas personas no están seguras de realizar esta operación en su base de datos y terminan teniendo impactos en el medio ambiente. Mi idea en esta publicación es ayudarlo a identificar y minimizar estos posibles impactos para que pueda aplicar estas configuraciones de seguridad a todos sus entornos.

Aplicación usando SA

El primer elemento que se debe verificar es si existe alguna aplicación que utilice el usuario “sa” para conectarse a la base de datos (créanme, existe). La forma más sencilla de identificar esto es preguntar al proveedor de la aplicación o al equipo de desarrollo.

Una forma que puede ayudarte a validar esta información e incluso poder identificar si este escenario está ocurriendo en tu entorno es consultando el DMV sys.dm_exec_sessions:

SELECT
    session_id,
    login_time,
    login_name,
    [program_name],
    [host_name],
    client_interface_name,
    [status],
    nt_domain,
    nt_user_name,
    original_login_name
FROM 
    sys.dm_exec_sessions
WHERE 
    session_id > 50
    AND security_id = 0x01

Resultado:

Bases de datos donde el usuario SA es propietario

Esta es una preocupación muy común entre los DBA: si desactivan al usuario SA y le cambian el nombre, puede ocurrir un problema en las bases de datos donde el usuario SA es el propietario. Sin embargo, puedes estar seguro de que no habrá ningún problema al realizar esto. Ya he hecho varias pruebas en varios entornos, tanto de prueba como de producción, y deshabilitar el usuario SA no tiene ningún impacto en esto.

Para probar lo que digo, aquí hay una demostración:

SELECT 
    A.database_id,
    A.[name],
    B.[name] AS [owner],
    A.create_date,
    A.state_desc,
    A.[compatibility_level],
    A.collation_name
FROM 
    sys.databases A
    JOIN sys.server_principals B ON A.owner_sid = B.[sid]


SELECT 
    [name],
    is_disabled
FROM
    sys.server_principals
WHERE
    principal_id = 1 -- sa

Resultado:

Trabajos donde el usuario SA es propietario

Así como cuando el usuario SA es propietario de una base de datos, no hay ningún impacto en la ejecución de los trabajos del Agente SQL al cambiar el nombre y desactivar el inicio de sesión “sa”. Pueden ser despreocupados y no necesitan cambiar el propietario de todos los trabajos para cambiar el nombre/desactivar sa.

Consulta utilizada para la demostración:

SELECT 
    A.[name] AS Ds_Job,
    B.[name] AS Ds_Owner,
    msdb.dbo.agent_datetime(C.run_date, C.run_time) AS Dt_Execucao,
    (CASE C.run_status
        WHEN 0 THEN '0 - Falha'
        WHEN 1 THEN '1 - Sucesso'
        WHEN 2 THEN '2 - Retry'
        WHEN 3 THEN '3 - Cancelado'
        WHEN 4 THEN '4 - Executando'
    END) AS Ds_Status,
    C.[message]
FROM
    msdb.dbo.sysjobs A
    JOIN sys.server_principals B ON A.owner_sid = B.[sid]
    JOIN msdb.dbo.sysjobhistory C ON C.job_id = A.job_id
WHERE
    C.step_id = 0 -- Geral

Resultado:

Servidor vinculado

Esta es probablemente la validación más difícil de realizar en el entorno, aunque también es bastante poco común. Si existe un Servidor Enlazado que apunta a tu instancia, donde la conexión al banco se realiza mediante el usuario “sa”, fijado en la LS, puedes tener problemas para desactivar y cambiar el nombre de este usuario.

Es difícil validar esto, porque debe ingresar a todas las instancias de su entorno que puedan tener un servidor vinculado que apunte a esta instancia específica y validar si se está produciendo este escenario:

No es muy común utilizar un Servidor Enlazado con un usuario fijo en la conexión, ya que cualquier usuario en la instancia remota podría ejecutar CUALQUIER COMANDO en la instancia de destino, ya que la conexión está llegando como “sa”, que es sysadmin, pero es una validación que se debe hacer para asegurar que el cambio no generará impactos.

Puede utilizar esta consulta para facilitar esta comprobación:

SELECT
    B.[name],
    B.product,
    B.[provider],
    B.[data_source],
    A.remote_name
FROM
    sys.linked_logins A
    JOIN sys.servers B ON B.server_id = A.server_id
WHERE
    A.server_id > 0
    AND A.local_principal_id = 0 -- SA

Objetos con IMPERSONATE usando SA

Es bastante común ver procedimientos y objetos que utilizan el comando EXECUTE AS para ejecutar tareas como si fueran un usuario más, especialmente para permitir que un usuario con pocos privilegios ejecute rutinas y comandos que requerirían más privilegios de los que tiene, creando así una elevación de privilegios. Si quieres profundizar más en SUPERSONATE y elevación de privilegios, te recomiendo leer mi artículo SQL Server: cómo utilizar EXECUTE AS para ejecutar comandos como otro usuario (suplantar inicio de sesión y usuario).

Para tranquilizarte, debes saber que no es posible utilizar EJECUTAR COMO USUARIO y hacerse pasar por el usuario “sa”, ya que es un usuario “especial”, es decir, una preocupación menos para ti.

Otros servicios

Y por último, para que puedas realizar tu cambio con total tranquilidad, te recomiendo que valides si existe algún servicio de Windows, informe de Reporting Services, alguna rutina de Power Shell, herramienta de monitoreo o algún proceso externo a SQL Server que pueda estar utilizando el usuario sa en tu entorno.

Al ser procesos externos y pueden ser específicos de tu empresa, no hay mucha “receta” para afrontar estas situaciones, pero no es nada común que un DBA permita que un servicio utilice el usuario “sa” para este tipo de operaciones, por lo que debe ser muy difícil encontrar este escenario.

Tenga calma y confianza al desactivar y cambiar el nombre del usuario “sa”, ya que es una buena práctica de seguridad para su entorno. Recuerde monitorear el registro de SQL Server después de este cambio para ver si aparecen mensajes de error de inicio de sesión usando "sa". Proporcioné una consulta que incluso puedes automatizar al principio de esta publicación 😉

Si identifica un problema, es posible que haya descubierto un intento de intrusión o un proceso no estándar en su empresa, que debe cambiarse urgentemente para utilizar otro usuario para conectarse a la base de datos.

Bueno amigos, ¡eso es todo!
Espero que te haya gustado este consejo, cambia el nombre y desactiva el usuario “sa” en tus entornos y ¡hasta la próxima!