MSSQL Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Pode ser possível enumerar usuários de domínio via injeção SQL dentro de um servidor MSSQL usando as seguintes funções MSSQL:
SELECT DEFAULT_DOMAIN()
: Obter o nome do domínio atual.
master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))
: Se você souber o nome do domínio (DOMAIN neste exemplo), esta função retornará o SID do usuário Administrator em formato hexadecimal. Isso parecerá com 0x01050000000[...]0000f401
, note como os últimos 4 bytes são o número 500 em formato big endian, que é o ID comum do usuário administrador.
Esta função permitirá que você saiba o ID do domínio (todos os bytes, exceto os últimos 4).
SUSER_SNAME(0x01050000000[...]0000e803)
: Esta função retornará o nome de usuário do ID indicado (se houver), neste caso 0000e803 em big endian == 1000 (geralmente este é o ID do primeiro usuário regular criado). Então você pode imaginar que pode forçar IDs de usuário de 1000 a 2000 e provavelmente obter todos os nomes de usuário dos usuários do domínio. Por exemplo, usando uma função como a seguinte:
Injeções SQL baseadas em erros geralmente se assemelham a construções como +AND+1=@@version--
e variantes baseadas no operador «OR». Consultas contendo tais expressões são geralmente bloqueadas por WAFs. Como uma forma de contornar isso, concatene uma string usando o caractere %2b com o resultado de chamadas de funções específicas que acionam um erro de conversão de tipo de dado nos dados desejados.
Alguns exemplos de tais funções:
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
Exemplo de uso da função USER_NAME()
:
Esses truques de SSRF foram retirados daqui
fn_xe_file_target_read_file
Requer permissão VIEW SERVER STATE
no servidor.
fn_get_audit_file
Requer a permissão CONTROL SERVER
.
fn_trace_gettabe
Requer a permissão CONTROL SERVER
.
xp_dirtree
, xp_fileexists
, xp_subdirs
Procedimentos armazenados como xp_dirtree
, embora não oficialmente documentados pela Microsoft, foram descritos por outros online devido à sua utilidade em operações de rede dentro do MSSQL. Esses procedimentos são frequentemente usados na exfiltração de dados fora de banda, como demonstrado em vários exemplos e posts.
O procedimento armazenado xp_dirtree
, por exemplo, é usado para fazer solicitações de rede, mas é limitado apenas à porta TCP 445. O número da porta não é modificável, mas permite a leitura de compartilhamentos de rede. O uso é demonstrado no script SQL abaixo:
É importante notar que este método pode não funcionar em todas as configurações de sistema, como em Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
rodando em um Windows Server 2016 Datacenter
com configurações padrão.
Além disso, existem procedimentos armazenados alternativos como master..xp_fileexist
e xp_subdirs
que podem alcançar resultados semelhantes. Mais detalhes sobre xp_fileexist
podem ser encontrados neste artigo do TechNet.
xp_cmdshell
Obviamente, você também poderia usar xp_cmdshell
para executar algo que aciona um SSRF. Para mais informações leia a seção relevante na página:
Criar uma UDF CLR (Função Definida pelo Usuário do Common Language Runtime), que é um código escrito em qualquer linguagem .NET e compilado em uma DLL, para ser carregado dentro do MSSQL para executar funções personalizadas, é um processo que requer acesso dbo
. Isso significa que geralmente é viável apenas quando a conexão com o banco de dados é feita como sa
ou com um papel de Administrador.
Um projeto do Visual Studio e instruções de instalação são fornecidos neste repositório do Github para facilitar o carregamento do binário no MSSQL como uma assembly CLR, permitindo assim a execução de requisições HTTP GET de dentro do MSSQL.
O núcleo dessa funcionalidade está encapsulado no arquivo http.cs
, que utiliza a classe WebClient
para executar uma requisição GET e recuperar conteúdo, conforme ilustrado abaixo:
Antes de executar o comando SQL CREATE ASSEMBLY
, é aconselhável executar o seguinte trecho SQL para adicionar o hash SHA512 da assembly à lista de assemblies confiáveis do servidor (visível através de select * from sys.trusted_assemblies;
):
Após adicionar a assembly com sucesso e criar a função, o seguinte código SQL pode ser utilizado para realizar requisições HTTP:
Um método conciso para extrair o conteúdo completo de uma tabela em uma única consulta envolve a utilização da cláusula FOR JSON
. Esta abordagem é mais sucinta do que usar a cláusula FOR XML
, que requer um modo específico como "raw". A cláusula FOR JSON
é preferida por sua brevidade.
Aqui está como recuperar o esquema, tabelas e colunas do banco de dados atual:
Non-standard whitespace characters: %C2%85 или %C2%A0:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
So for example, multiple queries such as:
Can be reduced to:
Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)