SQL Injection
Last updated
Was this helpful?
Last updated
Was this helpful?
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.
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.
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
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.
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.
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
Utilizando o bash
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.