Identificar por qué un usuario puede descartar una base de datos


8

Tengo un usuario del servidor SQL que tiene la capacidad de eliminar cualquier base de datos. He estado ejecutando el código a continuación para verificar los derechos que tiene el usuario en SQL Server, pero no he podido identificar cómo el usuario tiene la capacidad de eliminar bases de datos. ¿Existe un script sql que pueda ayudarme a identificar cómo este usuario puede eliminar dbs? ¿Hay un comando para negarles que caigan alguna base de datos? (SSMS no muestra al usuario como parte de la función dbcreator)

select USER_NAME(p.grantee_principal_id) AS principal_name,
    dp.type_desc AS principal_type_desc,
    p.class_desc,
    OBJECT_NAME(p.major_id) AS object_name,
    p.permission_name,
    p.state_desc AS permission_state_desc 
from    sys.database_permissions p
inner   JOIN sys.database_principals dp
on     p.grantee_principal_id = dp.principal_id
order by principal_name

El resultado de la consulta anterior proporciona los siguientes tres registros para el usuario si es útil.

clase_desc nombre_objeto nombre_permisión permiso_descripción_de_objeto OBJETO_COLUMNA xp_cmdshell EJECUTAR OTORGAR BASE DE DATOS NULL CONECTAR OTORGAR
BASE DE DATOS NULL CREAR BASE DE DATOS


¿Este usuario está cayendo bases de datos?
Zane

Puedo soltar bases de datos como ese usuario. Si. Si está preguntando si alguien ha usado la cuenta de manera melosa, prefiero no esperar para ver.
Grumoso

¿Cuál es el nivel general de permiso que tiene este usuario? ¿También es solo ciertas bases de datos o este servidor es ancho?
Zane

2
Observe qué permisos se requieren ( msdn.microsoft.com/en-us/library/ms178613.aspx ) e inviértalo en ingeniería inversa.
Thomas Stringer

Respuestas:


4

La consulta que tiene allí solo enumerará los permisos para la base de datos en la que la ejecuta. Una forma de obtener permiso para descartar una base de datos es ALTERAR CUALQUIER BASE DE DATOS, que es un permiso de nivel de servidor. Para verificarlos, intente esta consulta:

SELECT 
  [srvprin].[name] [server_principal],
  [srvprin].[type_desc] [principal_type],
  [srvperm].[permission_name],
  [srvperm].[state_desc] 
FROM [sys].[server_permissions] srvperm
  INNER JOIN [sys].[server_principals] srvprin
    ON [srvperm].[grantee_principal_id] = [srvprin].[principal_id]
WHERE [srvprin].[type] IN ('S', 'U', 'G')
ORDER BY [server_principal], [permission_name];

En otras palabras, el usuario podría estar obteniendo el permiso para eliminar bases de datos en el nivel de inicio de sesión del servidor en lugar del nivel de usuario de la base de datos.


1
Era el permiso Alter any Database
Lumpy

Sí, definitivamente no es un permiso que quieres que tenga Joe en Contabilidad.
KeithS

6

Sugeriría ejecutar esta consulta en el maestro

SELECT  
    [UserName] = CASE princ.[type] 
                    WHEN 'S' THEN princ.[name]
                    WHEN 'U' THEN ulogin.[name] COLLATE Latin1_General_CI_AI
                 END,
    [UserType] = CASE princ.[type]
                    WHEN 'S' THEN 'SQL User'
                    WHEN 'U' THEN 'Windows User'
                 END,  
    [DatabaseUserName] = princ.[name],       
    [Role] = null,      
    [PermissionType] = perm.[permission_name],       
    [PermissionState] = perm.[state_desc],       
    [ObjectType] = obj.type_desc,--perm.[class_desc],       
    [ObjectName] = OBJECT_NAME(perm.major_id),
    [ColumnName] = col.[name]
FROM    
    --database user
    sys.database_principals princ  
LEFT JOIN
    --Login accounts
    sys.login_token ulogin on princ.[sid] = ulogin.[sid]
LEFT JOIN        
    --Permissions
    sys.database_permissions perm ON perm.[grantee_principal_id] = princ.[principal_id]
LEFT JOIN
    --Table columns
    sys.columns col ON col.[object_id] = perm.major_id 
                    AND col.[column_id] = perm.[minor_id]
LEFT JOIN
    sys.objects obj ON perm.[major_id] = obj.[object_id]
WHERE 
    princ.[type] in ('S','U')
UNION
--List all access provisioned to a sql user or windows user/group through a database or application role
SELECT  
    [UserName] = CASE memberprinc.[type] 
                    WHEN 'S' THEN memberprinc.[name]
                    WHEN 'U' THEN ulogin.[name] COLLATE Latin1_General_CI_AI
                 END,
    [UserType] = CASE memberprinc.[type]
                    WHEN 'S' THEN 'SQL User'
                    WHEN 'U' THEN 'Windows User'
                 END, 
    [DatabaseUserName] = memberprinc.[name],   
    [Role] = roleprinc.[name],      
    [PermissionType] = perm.[permission_name],       
    [PermissionState] = perm.[state_desc],       
    [ObjectType] = obj.type_desc,--perm.[class_desc],   
    [ObjectName] = OBJECT_NAME(perm.major_id),
    [ColumnName] = col.[name]
FROM    
    --Role/member associations
    sys.database_role_members members
JOIN
    --Roles
    sys.database_principals roleprinc ON roleprinc.[principal_id] = members.[role_principal_id]
JOIN
    --Role members (database users)
    sys.database_principals memberprinc ON memberprinc.[principal_id] = members.[member_principal_id]
LEFT JOIN
    --Login accounts
    sys.login_token ulogin on memberprinc.[sid] = ulogin.[sid]
LEFT JOIN        
    --Permissions
    sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]
LEFT JOIN
    --Table columns
    sys.columns col on col.[object_id] = perm.major_id 
                    AND col.[column_id] = perm.[minor_id]
LEFT JOIN
    sys.objects obj ON perm.[major_id] = obj.[object_id]
UNION
--List all access provisioned to the public role, which everyone gets by default
SELECT  
    [UserName] = '{All Users}',
    [UserType] = '{All Users}', 
    [DatabaseUserName] = '{All Users}',       
    [Role] = roleprinc.[name],      
    [PermissionType] = perm.[permission_name],       
    [PermissionState] = perm.[state_desc],       
    [ObjectType] = obj.type_desc,--perm.[class_desc],  
    [ObjectName] = OBJECT_NAME(perm.major_id),
    [ColumnName] = col.[name]
FROM    
    --Roles
    sys.database_principals roleprinc
LEFT JOIN        
    --Role permissions
    sys.database_permissions perm ON perm.[grantee_principal_id] = roleprinc.[principal_id]
LEFT JOIN
    --Table columns
    sys.columns col on col.[object_id] = perm.major_id 
                    AND col.[column_id] = perm.[minor_id]                   
JOIN 
    --All objects   
    sys.objects obj ON obj.[object_id] = perm.[major_id]
WHERE
    --Only roles
    roleprinc.[type] = 'R' AND
    --Only public role
    roleprinc.[name] = 'public' AND
    --Only objects of ours, not the MS objects
    obj.is_ms_shipped = 0
ORDER BY
    princ.[Name],
    OBJECT_NAME(perm.major_id),
    col.[name],
    perm.[permission_name],
    perm.[state_desc],
    obj.type_desc--perm.[class_desc] 

Esto debería darle una idea bastante buena de los roles que tienen acceso a su base de datos maestra y ver el clima o no, el usuario tiene cualquiera de esos roles. También puede ejecutar esto en cualquiera de sus otras bases de datos para verificar los permisos del usuario en una base de datos por nivel de base de datos. Esta debería ser una herramienta importante para ayudar a rastrear esto.


Bonito script ....

4

¿Existe un script sql que pueda ayudarme a identificar cómo este usuario puede eliminar dbs?

Lo he usado varias veces con buenos resultados, la fuente del código a continuación se puede encontrar aquí :


SELECT SP1.[name] AS 'Login', 'Role: ' + SP2.[name] COLLATE DATABASE_DEFAULT AS 'ServerPermission'  
FROM sys.server_principals SP1 
  JOIN sys.server_role_members SRM 
    ON SP1.principal_id = SRM.member_principal_id 
  JOIN sys.server_principals SP2 
    ON SRM.role_principal_id = SP2.principal_id 
UNION ALL 
SELECT SP.[name] AS 'Login' , SPerm.state_desc + ' ' + SPerm.permission_name COLLATE DATABASE_DEFAULT AS 'ServerPermission'  FROM sys.server_principals SP  
  JOIN sys.server_permissions SPerm  
    ON SP.principal_id = SPerm.grantee_principal_id  
ORDER BY [Login], [ServerPermission];

¿Hay un comando para negarles que caigan alguna base de datos?

En la documentación aquí , los requisitos de seguridad para que un usuario elimine una base de datos se establecen como:

Requiere el permiso CONTROL en la base de datos, o ALTERAR CUALQUIER permiso de base de datos, o pertenecer a la función fija de base de datos db_owner

Puede negar explícitamente el permiso a uno mencionado anteriormente, pero comprenda que el nivel en el que lo niega puede no tener efecto como cree. Recuerdo haber leído un documento técnico que explicaba cómo SQL Server valida los permisos de un usuario tras la conexión, pero no puede ubicarlo en este momento. Si recuerdo, puedo negarles la conexión a una base de datos, pero el hecho de que el usuario sea parte del sysadminrol tiene prioridad.

Vería la auditoría específicamente para que el DROP DATABASEcomando sea seguro.


fue el alter cualquier permiso de base de datos. Gracias.
Bultos
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.