-- 3. 检查密码策略未启用的登录(高风险) SELECT name, is_policy_checked, is_expiration_checked, CASE WHEN is_policy_checked =0THEN'未启用密码策略' WHEN is_expiration_checked =0THEN'未启用密码过期' ELSE'合规' ENDAS[状态] FROM sys.sql_logins WHERE is_policy_checked =0OR is_expiration_checked =0;
-- 4. 检查sa账户状态(必须禁用或强密码) SELECT name, is_disabled, is_policy_checked, is_expiration_checked, modify_date FROM sys.sql_logins WHERE name ='sa';
-- 5. 查看最近登录失败记录(需启用登录审计) SELECT login_time, program_name, client_net_address, status_desc FROM sys.dm_exec_sessions s JOIN sys.dm_exec_connections c ON s.session_id = c.session_id LEFTJOIN sys.dm_exec_requests r ON s.session_id = r.session_id WHERE s.status='sleeping' ORDERBY s.login_time DESC;
-- 12. 查看当前活动连接和空闲时间 SELECT s.session_id, s.login_name, s.program_name, s.login_time, s.last_request_start_time, s.last_request_end_time, DATEDIFF(second, s.last_request_end_time, GETDATE())AS[空闲秒数], c.client_net_address FROM sys.dm_exec_sessions s LEFTJOIN sys.dm_exec_connections c ON s.session_id = c.session_id WHERE s.status='sleeping' AND DATEDIFF(second, s.last_request_end_time, GETDATE())>600-- 空闲超过10分钟 ORDERBY[空闲秒数]DESC;
二、访问控制(8.1.4.2)
2.1 权限管理与角色分离
测评项
T-SQL 查询语句
达标判据
查看固定服务器角色成员
SELECT * FROM sys.server_role_members
最小权限原则
检查数据库角色权限
SELECT * FROM sys.database_permissions
按库分配权限
查看对象级权限
SELECT * FROM sys.database_permissions WHERE class = 1
精细化授权
检查权限继承
SELECT * FROM fn_my_permissions(NULL, 'SERVER')
权限清晰
-- 13. 查看固定服务器角色及其成员 SELECT r.name AS[角色名], m.name AS[成员登录名], r.type_desc AS[角色类型] FROM sys.server_role_members rm JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id JOIN sys.server_principals m ON rm.member_principal_id = m.principal_id ORDERBY r.name, m.name;
-- 14. 查看具有sysadmin权限的登录(最高权限,需严格审查) SELECT l.name AS[登录名], l.type_desc AS[类型], r.name AS[服务器角色], '拥有完全控制权'AS[权限说明] FROM sys.server_role_members rm JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id JOIN sys.server_principals l ON rm.member_principal_id = l.principal_id WHERE r.name ='sysadmin' ORDERBY l.name;
-- 15. 查看每个数据库的用户和权限 EXEC sp_MSforeachdb ' USE [?]; SELECT DB_NAME() AS [数据库名], u.name AS [用户名], u.type_desc AS [类型], r.name AS [数据库角色], p.permission_name AS [权限], p.state_desc AS [权限状态] FROM sys.database_principals u LEFT JOIN sys.database_role_members rm ON u.principal_id = rm.member_principal_id LEFT JOIN sys.database_principals r ON rm.role_principal_id = r.principal_id LEFT JOIN sys.database_permissions p ON u.principal_id = p.grantee_principal_id WHERE u.type IN (''S'', ''U'', ''G'', ''R'') ORDER BY u.name; ';
-- 16. 查看特定对象的权限分配(以表为例) SELECT o.name AS[对象名], u.name AS[被授予者], p.permission_name AS[权限], p.state_desc AS[状态] FROM sys.database_permissions p JOIN sys.objects o ON p.major_id = o.object_id JOIN sys.database_principals u ON p.grantee_principal_id = u.principal_id WHERE p.class =1AND o.type='U'-- U=用户表 ORDERBY o.name, u.name;
-- 17. 检查直接授权(非角色授权,建议最小化) SELECT grantee.name AS[被授予者], grantor.name AS[授权者], p.permission_name, p.state_desc, o.name AS[对象名] FROM sys.database_permissions p JOIN sys.database_principals grantee ON p.grantee_principal_id = grantee.principal_id JOIN sys.database_principals grantor ON p.grantor_principal_id = grantor.principal_id LEFTJOIN sys.objects o ON p.major_id = o.object_id WHERE grantee.typeIN('S','U')-- 直接用户授权 AND p.major_id >0-- 排除数据库级权限 ORDERBY grantee.name;
-- 19. 检查guest用户权限(应禁用) EXEC sp_MSforeachdb ' USE [?]; SELECT DB_NAME() AS [数据库], name, permission_name, state_desc FROM sys.database_permissions p JOIN sys.database_principals u ON p.grantee_principal_id = u.principal_id WHERE u.name = ''guest''; ';
-- 24. 查看服务器审计规范(审计哪些操作) SELECT s.name AS[审计名], sp.name AS[规范名], sp.is_state_enabled AS[规范启用], audit_action_name AS[审计动作], class_desc AS[对象类型], is_group AS[是否动作组] FROM sys.server_audit_specifications sp JOIN sys.server_audits s ON sp.audit_guid = s.audit_guid JOIN sys.server_audit_specification_details spd ON sp.server_specification_id = spd.server_specification_id WHERE sp.is_state_enabled =1;
-- 25. 查看数据库级审计(所有数据库) EXEC sp_MSforeachdb ' USE [?]; IF EXISTS (SELECT 1 FROM sys.database_audits) SELECT DB_NAME() AS [数据库], name AS [审计名], type_desc, is_state_enabled, audit_file_path FROM sys.database_audits; ';
-- 26. 查看数据库审计规范 EXEC sp_MSforeachdb ' USE [?]; IF EXISTS (SELECT 1 FROM sys.database_audit_specifications) SELECT DB_NAME() AS [数据库], sp.name AS [规范名], sp.is_state_enabled, spd.audit_action_name, spd.class_desc FROM sys.database_audit_specifications sp JOIN sys.database_audit_specification_details spd ON sp.database_specification_id = spd.database_specification_id; ';
-- 27. 查看当前审计日志状态(最近写入时间) SELECT name, status_desc, type_desc, audit_file_path, (SELECTMAX(event_time)FROM sys.fn_get_audit_file(audit_file_path,DEFAULT,DEFAULT))AS[最后事件时间] FROM sys.server_audits WHERE type_desc ='FILE'AND status_desc ='STARTED';
-- 55. 查看非加密连接详情(风险) SELECT s.session_id, s.login_name, s.program_name, s.host_name, c.client_net_address, c.net_transport, c.encrypt_option FROM sys.dm_exec_sessions s JOIN sys.dm_exec_connections c ON s.session_id = c.session_id WHERE c.encrypt_option ='FALSE' AND c.net_transport ='TCP' AND s.is_user_process =1;
-- 61. 查看故障转移群集实例 SELECT cluster_name, type_desc, quorum_state_desc, quorum_type_desc FROM sys.dm_hadr_cluster;
-- 62. 查看AlwaysOn可用性组详细状态 SELECT ag.name AS[可用性组], ar.replica_server_name AS[副本服务器], ar.availability_mode_desc AS[可用性模式], ar.failover_mode_desc AS[故障转移模式], rs.role_desc AS[当前角色], rs.synchronization_health_desc AS[同步健康], rs.last_hardened_lsn FROM sys.availability_groups ag JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id JOIN sys.dm_hadr_availability_replica_states rs ON ar.replica_id = rs.replica_id;
-- 63. 查看数据库镜像(传统方式) SELECT database_id, db.name, mirroring_state_desc AS[镜像状态], mirroring_role_desc AS[镜像角色], mirroring_partner_name, mirroring_witness_name, mirroring_connection_timeout FROM sys.database_mirroring dm JOIN sys.databases db ON dm.database_id = db.database_id WHERE mirroring_guid ISNOTNULL;
-- 64. 查看复制配置(数据分发) SELECT name AS[发布名], database_id, is_snapshot_in_defaultfolder, compress_snapshot_files FROM distribution.dbo.MSpublications;
-- 65. 查看事务日志状态(恢复关键) SELECT db.name, db.log_reuse_wait_desc, ls.cntr_value/1024.0AS[日志大小MB], lu.cntr_value/1024.0AS[已用日志MB] FROM sys.databases db JOIN sys.dm_os_performance_counters ls ON db.name = ls.instance_name AND ls.counter_name ='Log File(s) Size (KB)' JOIN sys.dm_os_performance_counters lu ON db.name = lu.instance_name AND lu.counter_name ='Log File(s) Used Size (KB)' WHERE ls.object_name LIKE'%Databases%';
七、一键巡检脚本(SQL Server版)
-- ========================================== -- SQL Server 等保三级一键巡检脚本 -- 执行方式:在SQL Server Management Studio (SSMS) 中执行 -- 权限要求:sysadmin 或 securityadmin + 各数据库访问权限 -- ==========================================
-- 1.2 检查sa账户 SELECT@Result=CASE WHEN is_disabled =1THEN'PASS: sa账户已禁用' WHEN is_policy_checked =1AND is_expiration_checked =1THEN'WARN: sa已启用但受密码策略保护' ELSE'FAIL: sa账户处于活动状态且无密码策略' END FROM sys.sql_logins WHERE name ='sa';
-- 2.1 检查sysadmin权限分配 INSERTINTO#InspectionResults (Category, Item, Status, Detail) SELECT '访问控制', 'sysadmin权限审查', CASEWHENCOUNT(*)<=2THEN'PASS'ELSE'WARN'END, '具有sysadmin权限的登录数: '+ CAST(COUNT(*)AS NVARCHAR)+ ' (建议仅保留1-2个管理员)' FROM sys.server_role_members rm JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id JOIN sys.server_principals m ON rm.member_principal_id = m.principal_id WHERE r.name ='sysadmin';
-- 2.2 检查guest用户 INSERTINTO#InspectionResults (Category, Item, Status, Detail) SELECT '访问控制', 'guest用户权限', CASEWHENCOUNT(*)=0THEN'PASS'ELSE'FAIL'END, CASE WHENCOUNT(*)=0THEN'未发现guest用户直接授权' ELSE'发现'+ CAST(COUNT(*)AS NVARCHAR)+'个数据库中guest用户有权限' END FROM sys.databases db WHEREEXISTS( SELECT1FROM sys.database_permissions p JOIN sys.database_principals u ON p.grantee_principal_id = u.principal_id WHERE u.name ='guest'AND p.major_id >0 );
-- 审计管理 CREATE SERVER AUDIT audit TOFILE(PATH ='D:\Audit\'); CREATE SERVER AUDIT SPECIFICATION spec FOR SERVER AUDIT audit ADD (FAILED_LOGIN_GROUP); ALTER SERVER AUDIT audit WITH (STATE = ON);
-- 加密管理 CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256; ALTER DATABASE db SET ENCRYPTION ON;
-- 备份恢复 BACKUP DATABASE db TO DISK = 'D:\Backup\db.bak' WITH ENCRYPTION (ALGORITHM = AES_256, SERVER CERTIFICATE = cert); RESTORE DATABASE db FROM DISK = 'D:\Backup\db.bak';
-- 性能监控 EXEC sp_who2; SELECT * FROM sys.dm_exec_requests; SELECT * FROM sys.dm_exec_sessions WHERE status = 'sleeping';
参考标准:GB/T 22239-2019、GB/T 28448-2019、CIS Microsoft SQL Server Benchmark、Microsoft SQL Server Security Best Practices
适用版本:SQL Server 2016 SP3、2017 CU31、2019 CU22、2022 RTM及更高版本
执行权限:多数命令需 sysadmin 固定服务器角色,部分需 CONTROL SERVER 或特定数据库权限