Identifique por que um usuário pode descartar um banco de dados

8

Eu tenho um usuário do servidor sql que tem a capacidade de descartar qualquer banco de dados. Fiz o código abaixo para verificar os direitos que o usuário possui no SQL Server, mas não consegui identificar como o usuário tem a capacidade de descartar bancos de dados. Existe um script sql que pode me ajudar a identificar como esse usuário pode eliminar o dbs? Existe um comando para negar que eles descartem algum banco de dados? (O SSMS não está mostrando o usuário como parte da função 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

A saída da consulta acima fornece os três registros a seguir para o usuário, se for útil

class_desc nome_do_objeto nome_da_objeção permission_state_desc OBJECT_OR_COLUMN xp_cmdshell EXECUTE GRANT DATABASE NULL CONNECT GRANT
DATABASE NULL CREATE DATABASE GRANT

Grumoso
fonte
Esse usuário está descartando bancos de dados?
Zane
Eu posso descartar bancos de dados como esse usuário. Sim. Se você está perguntando se alguém usou a conta de forma melancólica, prefiro não esperar para ver.
Lumpy
Qual é o nível geral de permissão que esse usuário possui? Também é apenas alguns bancos de dados ou este servidor é amplo?
Zane
2
Veja quais permissões são necessárias ( msdn.microsoft.com/en-us/library/ms178613.aspx ) e faça a engenharia reversa.
Thomas Stringer

Respostas:

4

A consulta que você obteve lá listará apenas permissões para o banco de dados no qual você o executa. Uma maneira de obter permissão para descartar um banco de dados é ALTER ANY DATABASE, que é uma permissão no nível do servidor. Para verificá-las, tente 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];

Em outras palavras, o usuário pode estar obtendo a permissão para descartar bancos de dados no nível de logon do servidor, e não no nível de usuário do banco de dados.

mdoyle
fonte
11
Era a permissão Alterar qualquer banco de dados
Lumpy
Sim, definitivamente não é uma permissão que você deseja que Joe em Contabilidade tenha.
Keiths
6

Eu sugeriria executar esta consulta no mestre

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] 

Isso deve lhe dar uma boa idéia das funções que têm acesso ao seu banco de dados mestre e ver se o tempo está ou não em que o usuário tem uma dessas funções. Você também pode executar isso em qualquer um dos seus outros bancos de dados para verificar as permissões do usuário em um banco de dados por nível de banco de dados. Essa deve ser uma ferramenta importante para ajudar a rastrear isso.

Zane
fonte
Bom roteiro ....
4

Existe um script sql que pode me ajudar a identificar como esse usuário pode eliminar o dbs?

Eu usei isso algumas vezes com bons resultados, a fonte do código abaixo pode ser encontrada aqui :


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];

Existe um comando para negar que eles descartem algum banco de dados?

Indo para a documentação aqui , os requisitos de segurança para um usuário descartar um banco de dados são declarados como:

Requer a permissão CONTROL no banco de dados, permissão ALTER ANY DATABASE ou associação à função de banco de dados fixa db_owner

Você pode negar explicitamente a permissão a alguém mencionado acima, mas entender que o nível em que você nega pode não afetar o que você pensa. Lembro-me de ler um white paper que explicava como o SQL Server validava as permissões de um usuário na conexão, mas não pode localizá-lo agora. Se bem me lembro, posso negar a conexão com um banco de dados, mas o fato de o usuário fazer parte da sysadminfunção tem precedência.

Eu examinaria a auditoria especificamente para que o DROP DATABASEcomando fosse seguro.


fonte
foi a alteração de qualquer permissão do banco de dados. Obrigado.
amigos estão