¡¡¡Hola, chicos!!!
En este artículo me gustaría demostrar cómo mejorar la seguridad de tus instancias de SQL Server de una manera muy sencilla y utilizando una combinación de técnicas de Ocultamiento y Restricción de Acceso (recordando que en Seguridad tenemos 3 técnicas principales: Ocultamiento, Restricción de Acceso y Cifrado).
Lo que me gustaría discutir en este artículo es el privilegio VER CUALQUIER BASE DE DATOS, otorgado por defecto al rol público, que, como sugiere el nombre, permite que todos los inicios de sesión en la instancia puedan ver todas las bases de datos creadas en ella.
Mediante la técnica de Restricción de Acceso eliminaremos este privilegio del rol público, de manera que mediante el ocultamiento, un posible atacante no podrá identificar el nombre de las bases de datos de la instancia, dificultando mucho el éxito de sus ataques.
Un escenario muy común que ocurre en el día a día es que una misma instancia albergue varias aplicaciones diferentes. De nada sirve proteger tu aplicación y tu banco usando todas las buenas prácticas, si una de estas aplicaciones que comparte el servidor tiene vulnerabilidades y el usuario que se conecta al banco tiene el perfil sysadmin, por ejemplo, o incluso tiene acceso restringido pero expone el nombre de todas las bases de datos que están en la instancia.
Para demostrar que esto realmente existe, puedes utilizar la siguiente consulta para identificar a los usuarios que tienen este permiso en el banco:
SELECT
A.[name],
A.[sid],
A.[type_desc],
A.is_disabled,
B.[permission_name],
B.state_desc
FROM
sys.server_principals A
JOIN sys.server_permissions B ON A.principal_id = B.grantee_principal_id
WHERE
B.[permission_name] = 'VIEW ANY DATABASE'
AND B.[state] IN ('G', 'W')
O si sólo crees en los exámenes de práctica, allá vamos:
USE [master]
GO
CREATE LOGIN [teste_view_any_database] WITH PASSWORD=N'teste123', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
Creé el inicio de sesión "teste_view_any_database" solo con el comando anterior, sin otorgar NINGÚN permiso a este usuario. Me conectaré a la instancia con él y veamos qué puedo hacer:

Sin ningún permiso, pude enumerar todas las bases de datos y sus propiedades. Ahora voy a eliminar el permiso VER CUALQUIER BASE DE DATOS de la función pública y probaré nuevamente:
REVOKE VIEW ANY DATABASE FROM [public]
GO
Ahora otorgaré acceso de lectura a una de las bases:
USE [dirceuresende]
GO
CREATE USER [teste_view_any_database] FOR LOGIN [teste_view_any_database]
GO
ALTER ROLE [db_datareader] ADD MEMBER [teste_view_any_database]
GO
Ahora voy a probar si el usuario puede consultar los datos normalmente en las tablas y si puede consultar información de esta base de datos:

Como puede ver arriba, después de eliminar este permiso, el usuario normalmente puede consultar los datos. Lo que ya no podrá hacer es consultar información de instancia a través de sys.databases y sys.sysdatabases del DMV, ni abrir la lista de bases de datos a través de SQL Server Management Studio ni en el Explorador de Objetos:
Incluso SIN el permiso VER CUALQUIER BASE DE DATOS, el usuario que inicia sesión puede usar la instrucción USE [base de datos] para cambiar entre las bases de datos activas de la sesión a la que tiene acceso (permiso CONECTAR). Al cambiar la base de datos de la sesión, podrá consultar los datos de esa base de datos en las bases de datos sys.databases y sys.sysdatabases del DMV normalmente:
Es importante resaltar que, si este usuario es el propietario de la base de datos (db_owner), podrá listar esta base de datos incluso sin el permiso VER CUALQUIER BASE DE DATOS:

Sin embargo, entiendo que para un usuario que realiza consultas bancarias, esto puede resultar disruptivo y reducir considerablemente su productividad. Por lo tanto, un compromiso sería eliminar este permiso del rol público y crear un nuevo rol, que tenga este permiso, pero solo los usuarios humanos (sin usuarios del sistema) son parte de este rol:
USE [master]
GO
CREATE SERVER ROLE [Acesso_ViewAnyDatabase]
GO
GRANT VIEW ANY DATABASE TO [Acesso_ViewAnyDatabase]
GO
ALTER SERVER ROLE [Acesso_ViewAnyDatabase] ADD MEMBER [teste_view_any_database]
GO
En muchas empresas, los sistemas suelen utilizar inicios de sesión con autenticación de SQL Server y las personas se conectan mediante autenticación AD. En este escenario, la administración se puede hacer aún más fácil agregando el grupo AD predeterminado "Usuarios de dominio" a la pestaña Inicios de sesión y liberando el permiso VER CUALQUIER BASE DE DATOS para este grupo AD. De esta forma, todos los usuarios podrán ver las bases de datos, pero ningún sistema tendrá este acceso. Lo malo de este enfoque es que TODOS los usuarios de AD tendrán acceso a su base de datos.
Y finalmente, es importante señalar que sugiero no usar DENY VIEW ANY DATABASE en el rol público, ya que DENY anula el permiso GRANT e incluso otorgando acceso específico a los usuarios, el usuario no podrá listar las bases de datos.
Recordando que los usuarios administradores de sistemas pueden listar bases de datos normalmente incluso con REVOCAR o DENEGAR este permiso para el rol público.
IMPORTANTE: ANTES de eliminar este permiso en producción, PRUEBA tus sistemas varias veces para asegurarte de que no tendrán ningún impacto. Si su sistema necesita enumerar las bases de datos de la instancia para alguna operación, definitivamente tendrá un impacto (a menos que sea db_owner, pero entonces tenemos un problema de permisos, eh...)
Bueno chicos, espero que les haya gustado este post.
Creo que con pequeñas medidas, cuando se aplican en conjunto, podemos mejorar la seguridad de nuestro medio ambiente y hacer mucho más difícil el “trabajo” de posibles invasores.
Un fuerte abrazo y hasta luego.




Comentários (0)
Carregando comentários…