SQL Injection

O SQL injection, é uma das técnicas de vulnerabilidades web mais conhecida. Ela consiste em basicamente passar uma query SQL em um input que se o banco de dados não tiver um tratamento correto dessa entrada, pode acabar resultado em um vetor de ataque caso essa query seja maliciosa.

Vamos supor que o backend trata a entrada de um login da seguinte forma abaixo.

O problema é que a query que irá para o banco de dados não está sendo filtrada corretamente, passando os parâmetros exatamente como o usuário digita e isso pode ocasionar a vulnerabilidade.

Como pode ser explorado da maneira mais simples?

Vamos então utilizar o payload mais básico para explorar essa falha. A ideia a seguir, é utilizar o campo do usuário para bypassar a consulta. Primeiro temos que fechar as aspas simples e utilizar uma condição de "ou" para que assim a query retorne true e por fim comentar o resto para que seja ignorado, com isso irá trazer os resultados no banco de dados. O payload final fica da seguinte forma: ' or 1=1 # ou ' or 1=1 --

O comentário # e -- varia de acordo com o banco de dados.

Assim, no banco de dados vai retornar o primeiro usuário que a consulta buscar, autenticando assim na aplicação com este usuário.

SQL Injection Error Based

Esse é um tipo de injeção que retorna um erro para o usuário. Para triggar este erro, podemos passar, por exemplo, uma aspas simples para ver o que a aplicação retorna (essa aspas simples irá fechar a consulta no parâmetro que for passado). Se for vulnerável, geralmente irá vir uma mensagem com o seguinte erro:

You have an error in your SQL syntax;

Com isso, podemos utilizar o union do sql para unir uma nova consulta, e passar um %23 que significa o caractere # encodado, já que estamos enviando essas informações pela url (irá comentar o resto da query que estiver no banco). Além do "#", poderia ser passado também um ponto e vírgula ou uma aspas simples, depende de como a aplicação foi feita.

Assim é retornado a seguinte mensagem dizendo que o número de colunas é diferente do que foi passado.

Quando é inserido o número exato de colunas que tem no banco de dados, é retornado as informações (Agencia, Local e Telefone).

Podemos visualizar as tabelas para ficar mais claro o que está acontecendo.

Nesse caso, a aplicação só esta mostrando três colunas, a agência, local e telefone. No union, poderia ser passado qualquer valor além de 3, 4 e 5 como uma string por exemplo ("col1", "col2", "col3", "col4", "col5" ). Dessa forma que foi feito fica mais fácil para entender.

Sabendo quais colunas que está sendo retornado, podemos utilizar alguns comandos para pegarmos informações importantes.

A consulta ficou dessa forma

Information Schema

Agora que conseguimos algumas informações, vamos fazer consultas mais avançadas. Sabendo que o nome do banco de dados é dbmrtur, podemos consultar a information schema para conseguirmos mais informações.

Selecionando as tabelas

Selecionando as colunas

E por fim, selecionando os campos

Podemos utilizar o concat para concatenar as informações com dois pontos.

Do SQL Injection até o RCE

Para conseguirmos um RCE neste cenário, vamos fazer um escrever um arquivo no servidor. Podemos carregar arquivos do sistema operacional utilizando o load_file(), é ótimo para reconhecimento e ler arquivos sensíveis.

Para escrevermos o arquivo, podemos utilizar o INTO OUTFILE e passar o caminho que desejamos junto com o nome do nosso arquivo.

Porém, em determinados casos pode ser que não tenhamos permissão para fazer isso. Porém há um diretório no sistema que tem permissão de escrita. Sabendo disso, e tendo consciência que a aplicação interpreta PHP, podemos escrever um arquivo PHP com uma função system().

Pronto, não houve mais o erro de permissão e conseguimos criar o arquivo com a shell. Agora basta chamar o arquivo passando por parâmetro o que queremos executar.

Bypass addslashes

Algumas vezes, quando é passado um valor por parâmetro, o backend pode fazendo o tratamento colocando uma barra "\" para quebrar a consulta, assim dificultando que o sql injection seja explorado. Porém há uma forma de burlar convertendo as strings para decimais. Temos algumas opções para isso

Utilizando o mysql

select ascii("a");

Utilizando o bash

echo -n "teste" | od -An -tdC

Ou também utilizar um conversor para isso

Após fazer a conversão, ao invés de passar por parâmetro a string, basta utilizar char() com os decimais.

where tamble_schema=char(116, 101,115,116,101)

Last updated