NT-2026.09.25 DOSSIÊ

MSSQL E NMAP: ENUMERAÇÃO E EXPLORAÇÃO DE SQL SERVER COM SCRIPTS NSE

Do ms-sql-info ao xp_cmdshell: como os scripts NSE do Nmap enumeram versão, quebram credenciais, executam consultas, extraem hashes e disparam comandos no SQL Server pela porta 1433.

Capa do artigo MSSQL e Nmap: enumeração e exploração de SQL Server com scripts NSE, com fluxo Enumerar, Autenticar e Explorar

Por que o SQL Server exposto é um alvo recorrente

Microsoft SQL Server é o sistema de gerenciamento de banco de dados que, em redes corporativas Windows, costuma concentrar justamente o que um pentester procura: nomes de bancos, usuários, tabelas e — quando a configuração é fraca — credenciais que abrem a instância inteira. Por padrão, o serviço atende na porta TCP 1433, e é em torno dela que o Nmap mantém uma família dedicada de scripts NSE: os ms-sql-*.

A família cobre o arco completo de um teste: enumeração sem autenticação (versão da instância, informações NTLM do host), auditoria de credenciais (força bruta com dicionários, teste de senha vazia na conta sa) e operações autenticadas (execução de consultas, listagem de tabelas, extração de hashes e execução de comandos do sistema via xp_cmdshell). O percurso deste artigo segue exatamente essa progressão, na mesma sequência da demonstração que o inspira: reconhecer, autenticar e explorar.

Outros serviços de acesso remoto seguem lógica de reconhecimento semelhante — o teste de penetração na porta 3389 do RDP e o pivoting via Metasploit mostram como cada porta exposta amplia a superfície de ataque de um Windows acessível na rede.

Cenário e requisitos

A demonstração original foi montada com dois papéis:

  • Atacante: Kali Linux com Nmap.
  • Alvo: Windows 10 executando Microsoft SQL Server.

O Nmap é, na prática, uma coleção de scripts Lua — os NSE (Nmap Scripting Engine) — que realiza testes autenticados e não autenticados contra serviços MS-SQL. Não é preciso nada além do próprio Nmap e de dicionários de usuários e senhas quando o teste chega à auditoria de credenciais. O primeiro passo prático é simplesmente localizar quais scripts dessa família estão disponíveis na instalação.

Localizando os scripts NSE no Kali Linux

Os scripts NSE acompanham a instalação do Nmap em /usr/share/nmap/scripts. Para listar apenas os scripts de MS-SQL, a demonstração combina o locate com um filtro por nome:

locate *.nse | grep ms-sql

A saída traz a família completa — ms-sql-brute, ms-sql-empty-password, ms-sql-info, ms-sql-ntlm-info, ms-sql-query, ms-sql-tables e ms-sql-xp-cmdshell, entre outros. É com esse inventário em mãos que o teste progride de enumeração a exploração.

Terminal do Kali Linux mostrando a saída de locate com os arquivos ms-sql-brute.nse, ms-sql-info.nse, ms-sql-query.nse e demais scripts NSE de MS-SQL
Listagem dos scripts NSE ms-sql-* presentes em /usr/share/nmap/scripts no Kali Linux.

Enumeração de versão com ms-sql-info

O primeiro script da sequência tenta determinar informações de configuração e versão das instâncias de Microsoft SQL Server — sem nenhuma credencial. Segundo a documentação oficial, o ms-sql-info consulta o serviço SQL Server Browser (UDP 1434) e envia uma sonda à instância, que responde com o número exato de versão:

nmap -p 1433 --script ms-sql-info <IP-DO-ALVO>

Na demonstração, a resposta revelou o nome do servidor Windows (WIN-P830S778EQK), a instância SQLEXPRESS e a versão Microsoft SQL Server 2016 SP2 (build 13.00.5026.00). Para o atacante, esse único bloco de texto define o material de estudo: service pack, edição e versão exata do banco — insumo direto para pesquisa de vulnerabilidades conhecidas daquela build.

Terminal com a saída do nmap ms-sql-info exibindo Windows server name, instância SQLEXPRESS e versão Microsoft SQL Server 2016 SP2
Saída do ms-sql-info: instância SQLEXPRESS identificada como Microsoft SQL Server 2016 SP2 (build 13.00.5026.00).

Força bruta de credenciais com ms-sql-brute

Com o serviço reconhecido, o próximo passo é auditoria de senhas. O ms-sql-brute realiza força bruta contra o MS-SQL usando dicionários de usuários e senhas passados como argumentos — o timeout de conexão padrão do script é de 5 segundos:

nmap -p 1433 --script ms-sql-brute --script-args userdb=<USUARIOS>.txt,passdb=<SENHAS>.txt <IP-DO-ALVO>

Na demonstração, o teste recuperou credenciais válidas para três usuários da instância:

pavan : Password@123
aarti : Password@123
sa    : Password@1

A conta sa no resultado é o achado mais valioso: é o administrador embutido do SQL Server, com privilégio máximo sobre a instância. A documentação oficial alerta que, a partir do SQL Server 2005, políticas de bloqueio de conta podem interromper o script por instância — e que o argumento ms-sql-brute.ignore-lockout existe justamente para ignorar esse travamento, ao custo de gerar lockouts em massa (comportamento barulhento, do ponto de vista defensivo).

Terminal com a saída do nmap ms-sql-brute exibindo Credentials found com logins válidos recuperados pelos dicionários userdb e passdb
Força bruta com dicionários: credenciais válidas recuperadas para os logins aarti e sa.

Execução de consultas SQL com ms-sql-query

Credencial válida em mãos, o ms-sql-query executa qualquer consulta T-SQL contra a instância. A demonstração executa a stored procedure sp_databases, que lista os bancos de dados da instância — um catálogo de sistema documentado pela Microsoft que retorna nome e tamanho de cada banco:

nmap -p 1433 --script ms-sql-query --script-args mssql.username=<USUARIO>,mssql.password=<SENHA>,ms-sql-query.query="sp_databases" <IP-DO-ALVO>

A saída da demonstração listou o banco ignite dentre os bancos da instância. A partir daqui, o login sa é um canal de consulta arbitrário: o mesmo script que lista bancos poderia consultar tabelas, views e usuários do servidor.

Terminal com a saída do nmap ms-sql-query executando sp_databases e listando o banco ignite com tamanho de banco de dados
Execução de sp_databases via ms-sql-query: o banco ignite listado na instância.

Enumeração NetBIOS via NTLM com ms-sql-ntlm-info

De volta ao território sem credenciais, o ms-sql-ntlm-info enumera informações do host por trás do serviço. A técnica não tenta autenticar: o script envia uma requisição MS-TDS NTLM com um domínio inválido e credenciais nulas, e o serviço responde com uma mensagem NTLMSSP que revela dados do Windows — nome NetBIOS, nomes DNS e build do sistema operacional:

nmap -p 1433 --script ms-sql-ntlm-info <IP-DO-ALVO>

Na demonstração, a resposta trouxe NetBIOS_Computer_Name: WIN-P830S778EQK, os nomes DNS do host e Product_Version: 10.0.14393 — o build do Windows Server 2016. Para o atacante, é reconhecimento gratuito do sistema operacional; para o defensor, uma requisição NTLM com domínio inválido e credencial nula é assinatura clara de varredura.

Terminal com a saída do nmap ms-sql-ntlm-info exibindo Target_Name, NetBIOS_Computer_Name e Product_Version do host Windows
Resposta NTLMSSP do serviço: nome NetBIOS e Product_Version 10.0.14393 do host.

Extração de hashes com ms-sql-dump-hashes

O ms-sql-dump-hashes extrai os hashes de senha dos logins do SQL Server em formato pronto para quebra offline por ferramentas como o John the Ripper. A operação exige um login com privilégios de banco apropriados — na demonstração, a conta sa recuperada pela força bruta:

nmap -p 1433 --script ms-sql-dump-hashes --script-args mssql.username=<USUARIO>,mssql.password=<SENHA> <IP-DO-ALVO>

A captura da demonstração mostra os hashes 0x0200... de quatro logins, incluindo sa, aarti e pavan — os mesmos usuários revelados pela força bruta. A documentação oficial registra ainda que credenciais passadas por script-args têm precedência sobre credenciais descobertas por outros scripts.

Terminal com a saída do nmap ms-sql-dump-hashes exibindo hashes de senha de logins do SQL Server prefixados com 0x0200
Hashes 0x0200 dos logins da instância extraídos em formato pronto para John the Ripper.

Execução de comandos do sistema com ms-sql-xp-cmdshell

xp_cmdshell é uma extended stored procedure do SQL Server que executa comandos do sistema operacional a partir do banco. A Microsoft a desabilita por padrão — e com razão: habilitada, ela transforma qualquer login sysadmin em execução remota de comandos. O script ms-sql-xp-cmdshell tenta executar um comando via esse canal quando encontra a opção habilitada no alvo; a demonstração usou net user:

nmap -p 1433 --script ms-sql-xp-cmdshell --script-args mssql.username=<USUARIO>,mssql.password=<SENHA>,ms-sql-xp-cmdshell.cmd="net user" <IP-DO-ALVO>

A saída da demonstração lista as contas do Windows alvo — Administrator, Guest, DefaultAccount — comprovando que o comando rodou sob o contexto do serviço SQL. É o ponto em que o comprometimento deixa o banco de dados e alcança o sistema operacional.

Terminal com a saída do nmap ms-sql-xp-cmdshell executando net user e listando contas de usuário do Windows
Execução de net user via xp_cmdshell: contas do Windows alvo listadas pela saída do comando.

Conta sa com senha vazia: o cenário antes do teste

Se o administrador deixa o password em branco no login de um SQL Server, quem alcançar a porta 1433 entra direto. A demonstração investiga exatamente essa propriedade na conta sa: nas propriedades do login no SQL Server Management Studio, o modo de autenticação selecionado é SQL Server Authentication e os campos de senha permanecem vazios.

É o cenário ideal para o próximo script da família: sem dicionário, sem credencial, apenas a pergunta — a conta sa aceita senha vazia?

Diálogo Login Properties da conta sa no SQL Server Management Studio com opção SQL Server authentication e campo de senha vazio
Propriedades do login sa no SQL Server Management Studio: autenticação SQL selecionada com senha em branco.

Teste de senha vazia com ms-sql-empty-password

O ms-sql-empty-password tenta autenticar nos servidores Microsoft SQL usando senha vazia para a conta sa — o sysadmin embutido:

nmap -p 1433 --script ms-sql-empty-password <IP-DO-ALVO>

Na demonstração, o login foi bem-sucedido: sa: => Login Success. Com uma linha, a enumeração virou comprometimento — a conta de administração máxima da instância está aberta a qualquer autenticação em branco na rede.

Terminal com a saída do nmap ms-sql-empty-password exibindo Login Success para a conta sa com senha vazia
Login bem-sucedido com senha vazia: sa aceita autenticação em branco.

Enumeração de tabelas com ms-sql-tables

Encerrando o percurso, o ms-sql-tables lista as tabelas de cada banco de dados da instância, usando as credenciais passadas como argumento:

nmap -p 1433 --script ms-sql-tables --script-args mssql.username=<USUARIO>,mssql.password=<SENHA> <IP-DO-ALVO>

Na demonstração, o script percorreu o banco ignite e detalhou sua estrutura: a tabela Table_1 com a coluna passwords do tipo nchar(20). Uma coluna com esse nome é o tipo de achado que muda o rumo de um teste — senhas armazenadas em texto plano ou fracamente protegidas dentro de uma tabela enumerável.

Terminal com a saída do nmap ms-sql-tables listando a tabela Table_1 e a coluna passwords do banco ignite
Estrutura enumerada do banco ignite: tabela Table_1 com coluna passwords nchar(20).

Limitações e contexto de uso

Este artigo é documental: descreve a demonstração pública da referência, sem execução própria em laboratório. Os endereços IP, nomes de usuário e senhas visíveis nas capturas são artefatos do ambiente controlado da demonstração original, não infraestrutura real — devem ser lidos como evidência do walkthrough, nunca como credenciais válidas. Os scripts ms-sql-* exigem conectividade à porta 1433 (ou à 445 para instâncias via named pipes); redes que bloqueiem essas portas reduzem a superfície de todos os testes descritos. O conteúdo é destinado a profissionais de segurança, pesquisadores e estudantes em ambientes autorizados: laboratório próprio, CTF, pentest contratado com escopo definido ou pesquisa defensiva. Testar a porta 1433 de terceiros sem autorização é acesso não autorizado a sistema computacional.

Conclusão

O Nmap reduz o reconhecimento de um SQL Server exposto a uma sequência curta de scripts NSE: ms-sql-info revela a versão sem credencial, ms-sql-brute testa dicionários, ms-sql-ntlm-info entrega NetBIOS e build do sistema e, com um login válido, o atacante consulta bancos (ms-sql-query), lista tabelas (ms-sql-tables), extrai hashes quebráveis offline (ms-sql-dump-hashes) e executa comandos do sistema via xp_cmdshell. A conta sa com senha vazia demonstrada na fonte é o caso extremo: uma única linha converte enumeração em comprometimento.

Para o defensor, cada etapa tem assinatura observável e os controles são baratos: 1433 segmentada, política de senha forte, xp_cmdshell desabilitado e sysadmin restrito. A mesma suíte que enumera o banco serve para auditá-lo — testá-la contra a própria infraestrutura é a forma correta de validar esses controles.