Clique no banner para conhecer e adquirir o meu treinamento de Bancos de Dados no Azure

SQL Server - How to avoid brute force attacks on your database

Post Views 4,922 views
Esse post é a parte 13 de 21 da série Security and Auditing
Reading time 15 minutes

Fala galera!
Nesse artigo de hoje vou demonstrar como ocorrem ataques de força bruta ao SQL Server e como tentar se defender desse tipo de ataque.

O que é ataque de força bruta (Brute force attack)

Clique para exibir este conteúdo
Ataque de força bruta é a técnica mais simples e demorada para invadir sistemas e bancos de dados. Ela consiste em utilizar bases de dados de senhas para testar cada uma dessas senhas ou realizar uma verificação sistemática de todas as possíveis chaves e senhas até que uma delas consiga logar com sucesso no destino.

Esse tipo de ataque pode ser usado quando não é possível tomar vantagem de outras fraquezas em um sistema de criptografia (se existir) que tornariam a tarefa mais fácil, já que o tempo necessário para testar todas as senhas possíveis pode passar de alguns segundos (3 caracteres) para milhares de anos, de acordo com a quantidade de caracteres da senha e complexidade dos caracteres utilizados.

Ataque de força bruta no SQL Server

Clique para exibir este conteúdo
Por armazenar praticamente todos os dados de clientes e da empresa como um todo, os bancos de dados são potencialmente, um dos alvos mais buscados por invasores que tentam roubar informações ou simplesmente obter acesso privilegiado à esse banco para outro fim qualquer. Um exemplo clássico disso é tentar acessar o banco com um usuário com poderes administrativos para conseguir parar o serviço do SQL Server e assim executar um comando malicioso, como o ransomware WannaCry, por exemplo, que exige que os bancos não estejam em uso para conseguir criptografar os dados.

Para que seja possível identificar se a sua instância SQL Server está sofrendo ataques, a primeira coisa que você deve fazer é ativar a auditoria de falhas de conexão (já vem ativado por padrão), como demonstrado no print abaixo:

Isso também pode ser alterado utilizando comandos T-SQL:

Uma vez que você se certificou que falhas de logins já estão sendo auditadas, qualquer tentativa de conexão que seja feita sem sucesso, devido à senha incorreta ou usuário que não existe, será logada no ERRORLOG do SQL Server, que você pode acessar assim:

E depois visualizar os registros:

Além disso, você também pode utilizar as Extended Procedures sp_readerrorlog e xp_readerrorlog para conseguir visualizar o conteúdo do log do SQL Server utilizando linha de comando.

Para saber mais sobre o funcionamento dessas duas procedures, sugiro que estude o código que vou mostrar ainda nesse artigo e leia também o excelente artigo ERRORLOG – O básico, que explica tudo sobre o ERRORLOG do SQL Server.

Como identificar ataque de força bruta no SQL Server

Clique para exibir este conteúdo
Agora que mostrei como ativar a auditoria de falhas de conexão e também onde e como podemos consultas essas informações, vamos começar a trabalhar com esses dados para atingir nosso objetivo: Como identificar ataque de força bruta no SQL Server.

Em uma utilização básica, vamos utilizar a xp_readerrorlog para ler o arquivo de log atual (0) e filtrar no log as falhas de login:

Result:

Vamos agora executar novamente esse comando, mas armazenando o retorno essa SP numa tabela temporária e identificando o IP e o usuário dessa mensagem:

Result:

Caso você queira analisar não somente o último arquivo de log, mas sim todos eles, você precisará da sp_enumerrorlogs, para listar os logs existentes e assim montar o seu loop entre os arquivos. Aproveitei para refinar mais a buscar e trazer apenas tentativas com falha por senha incorreta e login inexistente (existem outros tipos, como usuário sem permissão no database padrão):

Result:

Com esses dados, já podemos começar a identificar quais usuários e origens dos ataques aos usuários:

Result:

Important: Um ponto interessante que podemos levar em consideração, é criar uma lista de exceções com IP’s que não podem ser bloqueados, mesmo em casos onde tenham muitas conexões com falha, como por exemplo, o IP fixo da própria empresa, IP do servidor de aplicação, etc.

Como monitorar possíveis invasões por força bruta

Clique para exibir este conteúdo
Como esse assunto é de extrema importância, não dá pra contar com a sorte de você lembrar de ficar acompanhando esse tipo de evento no seu ambiente. Caso ele comece a sofrer um possível ataque, você deve agir o quanto antes e nada melhor que um alerta para te deixar ciente quando esse tipo de comportamento começar a sugir nas instâncias que você administra.

Para atingir esse objetivo, vou utilizar o Database Mail do SQL Server, que vai nos permitir enviar e-mails pelo banco de dados quando houverem um determinado número de falhas de conexão e a Stored Procedure stpExporta_Tabela_HTML_Output, que permite armazenar em uma variável, o conteúdo de uma tabela no banco de dados no formato de uma tabela HTML, ideal para enviar em e-mail.

O script abaixo vai buscar os eventos de falha de login da última hora e enviar esses registros por e-mail (caso ultrapassem o limite definido para não enviar muito e-mail e virar SPAM).

Caso você precise de mais informações sobre como ativar e configurar esse recurso, sugiro que leia o meu artigo SQL Server – Como ativar e configurar o Database mail para enviar e monitorar e-mails pelo banco de dados (sp_send_dbmail).

Código do monitoramento:

Result:

Como evitar possíveis invasões por força bruta

Clique para exibir este conteúdo
Chegamos agora na parte final deste artigo, onde vou abordar sobre possíveis soluções para este problema tão comum, que é o ataque de força bruta. A alternativa que é possível ser implementada no SQL Server, é criar uma lista de IPs para bloquear e executar essa lista através de algum script externo, como PowerShell ou mesmo o agendador de tarefas do Windows, para criar regras no Firewall do Windows para bloquear esses IP’s quando eles atingirem uma determinada quantidade de tentativas de conexão sem sucesso.

Para exportar a lista de IP’s para um arquivo no servidor, podemos utilizar diversos método como xp_cmdshell, OLE Automation ou SQLCLR, mas vou optar por xp_cmdshell nesse exemplo, por ser o mais simples de implementar. Uma vez que o arquivo foi exportado no formato bat já com o comandos a serem executados, basta agendar a execução desse script no agendador de tarefas do Windows e configurar a execução para utilizar um usuário com permissão de Administrador.

Outra alternativa viável é deixar que o próprio SQL Server já execute os comandos para adicionar os IP’s no Firewall ao invés de exportar um arquivo bat com esses comandos. Para que isso seja possível, o usuário que inicia o serviço do SQL Server deve ser Administrador local da máquina, o que acaba não sendo algo tão recomendável do ponto de vista de segurança.

Um ponto importante a ser demonstrado de novo é sobre a lista de exceções, para evitar que IP’s importantes sejam bloqueados durante algum teste ou erro temporário.

Para finalizar esse tema, vou disponibilizar o script completo que:

  • identifica os logs
  • categoriza por IP e usuário
  • armazena um histórico das tentativas
  • busca as ocorrências de falha de conexão desde a última execução da Procedure
  • lista de exeções implementada
  • envia e-mail de alerta
  • gera um arquivo .bat no disco com os comandos para bloquear no Windows Firewall os IP’s com mais de N falhas de conexão

Código-fonte do script:

Script de bloqueio de IP’s gerado (Executar como Administrador):

Segurança no SQL Server – Assunto SÉRIO!

Após demonstrar algumas formas de atenuar o problema de invasão por força bruta identificando e bloqueando os IP’s que estão tentando invadir o ambiente no Windows Firewall, precisamos falar sério sobre Segurança. Infelizmente é muito comum ver ambientes totalmente desleixados no quesito segurança do banco de dados, onde usuários de aplicação possuem permissão de sysadmin, usuários que acessam o banco também como sysadmin, usuários com privilégios elevados e senhas frágeis, xp_cmdshell e query dinâmica sendo práticas comuns nos ambientes e muitos outros cenários bem preocupantes.

Sobre o cenário desse post, que é o ataque de força bruta, a grande maioria dos casos ocorre pelo fato do banco de dados estar publicado para Internet, facilitando bastante a entrada de possíveis invasores e a possibilidade de alguém tentar atacar a sua instância. Em muitos casos, isso ocorre quando o servidor do banco é o mesmo da aplicação, o que não é uma boa prática nem para o banco nem para a aplicação.

O banco acaba disputando recursos do servidor (CPU, Memória, Disco, Rede) com a aplicação e ainda tem que ficar visível e exposto para Internet, sem a possibilidade da criação de Whitelist (somente os endereços da lista possuem acesso ao servidor), já que isso iria impedir que os usuários acessem a aplicação. Isso sem falar que se o servidor da aplicação for compretido, os dados do banco podem ser acessados também, o que é um cenário catastrófico.

Um outro ponto que deve ser levantado também, é que mesmo quando o ataque de força bruta é realizado no ambiente, mesmo que ele não tenha sucesso ele ainda consegue prejudicar a empresa, pois enquanto ele fica tentando as milhares de senhas para invadir o banco, esse processo acaba consumindo muitos recursos do servidor de forma desnecessária.

Além disso, muitos ransomwares, com o WannaCry (o que devastou a internet ano passado) geralmente são precedidos por ataques de força bruta para conseguir acesso ao banco de dados de modo que o atacante consiga colocar os bancos offline para que o Ransonware depois consiga criptografar os arquivos de dados (mdf) e log (ldf).

O que fazer então para resolver isso?

Bom, o PRIMEIRO passo para isso é deixar o banco invisível para a Internet. Se tiver que separar o banco da aplicação e montar 1 servidor para cada um, que o faça então, criando uma VPN para realizar a comunição entre os 2 servidores (caso estejam em redes diferentes, como o Azure). Se a empresa não tiver condições de bancar um servidor para cada um e a aplicação for acessada pela Internet, por vários IP’s e não existe possibilidade de fazer uma whitelist para limitar os IP’s que vão acessar o servidor, o jeito é implementar a solução que disponibilizei acima e torcer para não acontecer o pior, já que o script desse artigo vai bloquear apenas tentar de acesso ao banco, mas existem N outros tipos de ataques para acessar o servidor, como ataques RDP, SSH, etc..

O SEGUNDO passo é desativar e renomear o usuário SA e qualquer outro usuário padrão do SQL Server, já que esses usuários são os principais alvos de ataques por força bruta, uma vez que o invasor já sabe o login e precisa apenas da senha.

O TERCEIRO passo é evitar ao máximo a utilização de logins com autenticação SQL Server, pois o banco que tem que controlar e gerenciar essas senhas. Além disso, o hash dessas senhas fica armazenado no banco e pode ser facilmente quebrado e validado sem gerar nem exceção no log do SQL Server, conforme demonstrei no artigo SQL Server – Como identificar senhas frágeis, vazias ou iguais ao nome do usuário. Utilize sempre que possível, autenticação do Windows AD, eliminando a necessidade de digitar senhas e o SQL Server não tem informações do hash e nem da senha.

O QUARTO passo é implementar o monitoramento desse artigo e ficar sempre de olho nesse relatório, bloqueando no Firewall do Windows (ou do Azure) os IP’s que estão com muitas falhas de conexão. Esse trabalho deve ser CONSTANTE e não só de forma pontual. Deixou o banco de dados disponível para internet, então agora aguenta. Se possível, utilizar essa lista de IP’s para bloquear esses endereços a nível de organização, no Firewall geral da rede e não apenas no servidor de banco. Você também pode pegar listas de Range de IPs por País e tentar liberar apenas os IPs do Brasil (Whitelist mais abrangente).

O QUINTO passo é revisar periodicamente a senha dos logins SQL Server do seu ambiente. É muito importante que as senhas desses usuários seja alterada PELO MENOS 1X POR ANO. Além disso, as senhas desses usuários devem ser grandes e complexas (eu utilizo sempre senhas com 50 caracteres ou mais, sendo letras, números e símbolos). Além disso, é importante ter uma política anual (pelo menos) de revisão de acessos. sysadmin é só pra DBA e db_owner nem deveria ser usado (salve raríssimas exceções).

Bom pessoal, esse foi o artigo sobre Ataque de força bruta no SQL Server. Espero que vocês tenham gostado dessa linha de Segurança, que é uma área que devo investir bastante tempo estudando e escrevendo artigos esse ano e é o tema da minha palestra no MVPConf Latam 2019.

Um grande abraço e até o próximo post.