Определите, почему пользователь может удалить базу данных

8

У меня есть пользователь сервера sql, который может удалить любую базу данных. Я запускаю приведенный ниже код, чтобы проверить права, которые пользователь имеет в SQL Server, но не смог определить, как пользователь имеет возможность удалять базы данных. Есть ли сценарий SQL, который может помочь мне определить, как этот пользователь может отбрасывать БД? Есть ли команда, чтобы запретить им сбросить какие-либо базы данных? (SSMS не показывает пользователя как часть роли 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

Вывод запроса выше предоставляет следующие три записи для пользователя, если это полезно

class_desc object_name PERMISSION_NAME permission_state_desc OBJECT_OR_COLUMN xp_cmdshell ВЫПОЛНИТЬ GRANT DATABASE NULL CONNECT GRANT
DATABASE NULL CREATE DATABASE ГРАНТ

комковатый
источник
Этот пользователь удаляет базы данных?
Зейн
Я могу отбросить базы данных от имени этого пользователя. Да. Если вы спросите, использовал ли кто-нибудь аккаунт безумно, я бы предпочел не ждать.
Кусок
Какой общий уровень разрешений у этого пользователя? Кроме того, это только определенные базы данных или этот сервер в целом?
Зейн
2
Посмотрите, какие разрешения требуются ( msdn.microsoft.com/en-us/library/ms178613.aspx ) и перепроектируйте его.
Томас Стрингер

Ответы:

4

Полученный вами запрос будет содержать список разрешений только для той базы данных, с которой вы его выполняете. Одним из способов получить разрешение на удаление базы данных является ALTER ANY DATABASE, которая представляет собой разрешение на уровне сервера. Чтобы проверить это, попробуйте этот запрос:

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

Другими словами, пользователь может получать разрешение на удаление баз данных на уровне входа в систему сервера, а не на уровне пользователя базы данных.

mdoyle
источник
1
Это было разрешение Alter any Database
Lumpy
Да, определенно не то разрешение, которое вы хотели бы иметь у Джо в бухгалтерии.
KeithS
6

Я бы предложил запустить этот запрос на мастере

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] 

Это должно дать вам довольно хорошее представление о ролях, которые имеют доступ к вашей основной базе данных и видят погоду или нет, у пользователя есть какие-либо из этих ролей. Вы также можете запустить это для любой другой базы данных, чтобы проверить разрешения пользователя для базы данных по уровню базы данных. Это должно быть важным инструментом, чтобы помочь отследить это.

Зейн
источник
Хороший сценарий ....
4

Есть ли сценарий SQL, который может помочь мне определить, как этот пользователь может отбрасывать БД?

Я использовал это несколько раз с некоторыми хорошими результатами, источник кода ниже можно найти здесь :


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

Есть ли команда, чтобы запретить им сбросить какие-либо базы данных?

Переходя к документации здесь , требования безопасности для пользователя для удаления базы данных сформулированы как:

Требуется разрешение CONTROL для базы данных, или разрешение ALTER ANY DATABASE, или членство в предопределенной роли базы данных db_owner.

Вы можете явно отказать в разрешении одному из упомянутых выше, но понимаете, что уровень, на котором вы это отрицаете, может не повлиять так, как вы думаете. Я помню, как читал технический документ, в котором рассказывалось, как SQL Server проверяет разрешения пользователя при подключении, но не может найти его прямо сейчас. Если я вспоминаю, я могу отказать им в подключении к базе данных, но тот факт, что пользователь является частью sysadminроли, имеет приоритет.

Я бы посмотрел на одитинг специально, чтобы DROP DATABASEкоманда была в безопасности.


источник
это было изменение любого разрешения базы данных. Спасибо.
Кусок