MS Access SQL Injection
Last updated
Last updated
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
A concatenação de strings é possível com os caracteres & (%26)
e + (%2b)
.
Não há comentários no MS Access, mas aparentemente é possível remover o último de uma consulta com um caractere NULL:
Se isso não estiver funcionando, você sempre pode corrigir a sintaxe da consulta:
Elas não são suportadas.
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.
Assim como o TOP, você pode usar LAST
que irá obter as linhas do final.
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.
Isso permitirá que você exfiltre valores da tabela atual sem precisar saber o nome da tabela.
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.
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:
Fique à vontade para verificar isso no playground online.
Usando a técnica de encadeamento de iguais, você também pode forçar nomes de tabelas com algo como:
Você também pode usar uma maneira mais tradicional:
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
Há outra lista em http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
Você pode forçar os nomes das colunas atuais com o truque de encadeamento de iguais com:
Ou com um group by:
Ou você pode forçar os nomes das colunas de uma tabela diferente com:
Já discutimos a técnica de encadeamento de iguais para despejar dados da tabela atual e de outras tabelas. Mas há outras maneiras:
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.
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
De aqui você pode ver uma consulta para obter os nomes das tabelas:
No entanto, note que é muito típico encontrar SQL Injections onde você não tem acesso para ler a tabela MSysObjects
.
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.
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
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.
Access PassView é 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.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)