ユーザーがデータベースを削除できる理由を特定する


8

データベースを削除できるSQLサーバーユーザーがいます。以下のコードを実行して、SQL Serverでのユーザーの権限を確認しましたが、ユーザーがデータベースを削除する機能を特定できませんでした。このユーザーがdbを削除する方法を特定するのに役立つ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

上記のクエリの出力は、役立つ場合、ユーザーに次の3つのレコードを提供します

class_desc object_name permission_name permission_state_desc OBJECT_OR_COLUMN xp_cmdshell EXECUTE GRANT DATABASE NULL CONNECT GRANT
DATABASE NULL CREATE DATABASE GRANT


このユーザーはデータベースを削除していますか?
Zane

そのユーザーとしてデータベースを削除できます。はい。誰かが悪意を持ってアカウントを使用したかどうかを尋ねている場合、私は見たくないです。
Lumpy

このユーザーが持っている一般的な権限のレベルは何ですか?また、特定のデータベースのみですか、それともこのサーバー全体ですか?
ゼーン

2
必要なアクセス許可(msdn.microsoft.com/en-us/library/ms178613.aspx)を確認し、それをリバースエンジニアリングします。
Thomas Stringer

回答:


4

取得したクエリには、それを実行したデータベースの権限のみがリストされます。データベースを削除する権限を取得する1つの方法は、サーバーレベルの権限である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];

つまり、ユーザーは、データベースユーザーレベルではなくサーバーログインレベルでデータベースを削除する権限を取得している可能性があります。


1
これは、データベースの変更権限
Lumpy

ええ、間違いなく、Joe in Accountingに許可を与える必要はありません。
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

このユーザーがdbを削除する方法を特定するのに役立つ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コマンドが安全であることを確認するために、特に監査を検討します。


それはデータベースのパーミッションの変更でした。ありがとうございました。
2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.