SQL Injection em 2025: Ainda Funciona? Como Detectar e Explorar

Injeção de SQL (SQLi) é uma vulnerabilidade de segurança na web que permite que um invasor interfira nas consultas que um aplicativo realiza ao seu banco de dados. Isso pode permitir que um invasor visualize dados que normalmente não consegue recuperar. Isso pode incluir dados pertencentes a outros usuários ou quaisquer outros dados que o aplicativo possa acessar. Em muitos casos, um invasor pode modificar ou excluir esses dados, causando alterações persistentes no conteúdo ou comportamento do aplicativo.

Em algumas situações, um invasor pode escalar um ataque de injeção de SQL para comprometer o servidor subjacente ou outra infraestrutura de back-end. Isso também pode permitir ataques de negação de serviço.

Qual é o impacto de um ataque de injeção de SQL bem-sucedido?

Um ataque de injeção de SQL bem-sucedido pode resultar em acesso não autorizado a dados confidenciais, como:

  • Senhas.
  • Detalhes do cartão de crédito.
  • Informações pessoais do usuário.

Ataques de injeção de SQL têm sido utilizados em muitas violações de dados de alto perfil ao longo dos anos. Isso tem causado danos à reputação e multas regulatórias. Em alguns casos, um invasor pode obter uma backdoor persistente nos sistemas de uma organização, levando a um comprometimento de longo prazo que pode passar despercebido por um longo período.

Como detectar vulnerabilidades de injeção de SQL

Você pode detectar injeção de SQL manualmente usando um conjunto sistemático de testes em cada ponto de entrada do aplicativo. Para isso, você normalmente enviaria:

  • O caractere de aspas simples 'e procure por erros ou outras anomalias.
  • Alguma sintaxe específica de SQL que avalia o valor base (original) do ponto de entrada e um valor diferente, e procura diferenças sistemáticas nas respostas do aplicativo.
  • Condições booleanas como OR 1=1OR 1=2, e procure diferenças nas respostas do aplicativo.
  • Cargas úteis projetadas para disparar atrasos de tempo quando executadas em uma consulta SQL e procurar diferenças no tempo de resposta.
  • Cargas úteis OAST projetadas para acionar uma interação de rede fora de banda quando executadas dentro de uma consulta SQL e monitorar quaisquer interações resultantes.

Como alternativa, você pode encontrar a maioria das vulnerabilidades de injeção de SQL de forma rápida e confiável usando o Burp Scanner.

Injeção de SQL em diferentes partes da consulta

A maioria das vulnerabilidades de injeção de SQL ocorre dentro da WHEREcláusula de uma SELECTconsulta. A maioria dos testadores experientes está familiarizada com esse tipo de injeção de SQL.

No entanto, vulnerabilidades de injeção de SQL podem ocorrer em qualquer local da consulta e em diferentes tipos de consulta. Outros locais comuns onde a injeção de SQL ocorre são:

  • Em UPDATEdeclarações, dentro dos valores atualizados ou da WHEREcláusula.
  • Em INSERTdeclarações, dentro dos valores inseridos.
  • Em SELECTinstruções, dentro do nome da tabela ou coluna.
  • Em SELECTdeclarações, dentro da ORDER BYcláusula.

Exemplos de injeção de SQL

Existem muitas vulnerabilidades, ataques e técnicas de injeção de SQL que ocorrem em diferentes situações. Alguns exemplos comuns de injeção de SQL incluem:

Recuperando dados ocultos

Imagine um aplicativo de compras que exibe produtos em diferentes categorias. Quando o usuário clica na categoria Presentes , seu navegador solicita a URL:https://insecure-website.com/products?category=Gifts

Isso faz com que o aplicativo faça uma consulta SQL para recuperar detalhes dos produtos relevantes do banco de dados:SELECT * FROM products WHERE category = 'Gifts' AND released = 1

Esta consulta SQL solicita que o banco de dados retorne:

  • todos os detalhes ( *)
  • da productsmesa
  • onde categoryestáGifts
  • releasedé 1.

A restrição released = 1está sendo usada para ocultar produtos que não foram lançados. Podemos supor que, para produtos não lançados, released = 0.

O aplicativo não implementa nenhuma defesa contra ataques de injeção de SQL. Isso significa que um invasor pode construir o seguinte ataque, por exemplo:https://insecure-website.com/products?category=Gifts'--

Isso resulta na consulta SQL:SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1

É crucial observar que _ --é um indicador de comentário em SQL. Isso significa que o restante da consulta é interpretado como um comentário, removendo-o efetivamente. Neste exemplo, isso significa que a consulta não inclui mais _ AND released = 1. Como resultado, todos os produtos são exibidos, incluindo aqueles que ainda não foram lançados.

Você pode usar um ataque semelhante para fazer com que o aplicativo exiba todos os produtos em qualquer categoria, incluindo categorias que eles não conhecem:https://insecure-website.com/products?category=Gifts'+OR+1=1--

Isso resulta na consulta SQL:SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1

A consulta modificada retorna todos os itens onde o categoryé Gifts, ou 1é igual a 1. Como 1=1sempre, a consulta retorna todos os itens.

Aviso

Tenha cuidado ao injetar a condição OR 1=1em uma consulta SQL. Mesmo que pareça inofensivo no contexto em que você está injetando, é comum que aplicativos usem dados de uma única solicitação em várias consultas diferentes. Se a sua condição atingir uma instrução UPDATE“ou DELETE“, por exemplo, isso pode resultar em perda acidental de dados.

Subvertendo a lógica da aplicação

Imagine um aplicativo que permite que os usuários efetuem login com um nome de usuário e uma senha. Se um usuário inserir o nome de usuário wienere a senha bluecheese, o aplicativo verifica as credenciais executando a seguinte consulta SQL:SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'

Se a consulta retornar os detalhes de um usuário, o login foi bem-sucedido. Caso contrário, será rejeitado.

Nesse caso, um invasor pode efetuar login como qualquer usuário sem a necessidade de uma senha. Ele pode fazer isso usando a sequência de comentários SQL --para remover a verificação de senha da WHEREcláusula da consulta. Por exemplo, enviar o nome de usuário administrator'--e uma senha em branco resulta na seguinte consulta:SELECT * FROM users WHERE username = 'administrator'--' AND password = ''

Esta consulta retorna o usuário usernameadministratorefetua login com sucesso no invasor como esse usuário.

Recuperando dados de outras tabelas de banco de dados

Nos casos em que o aplicativo responde com os resultados de uma consulta SQL, um invasor pode usar uma vulnerabilidade de injeção de SQL para recuperar dados de outras tabelas no banco de dados. Você pode usar a UNIONpalavra-chave para executar uma consulta adicional SELECTe anexar os resultados à consulta original.

Por exemplo, se um aplicativo executa a seguinte consulta contendo a entrada do usuário Gifts:SELECT name, description FROM products WHERE category = 'Gifts'

Um invasor pode enviar a entrada:' UNION SELECT username, password FROM users--

Isso faz com que o aplicativo retorne todos os nomes de usuários e senhas, juntamente com os nomes e descrições dos produtos.

Ler mais

Vulnerabilidades de injeção cega de SQL

Muitas instâncias de injeção de SQL são vulnerabilidades cegas. Isso significa que o aplicativo não retorna os resultados da consulta SQL nem os detalhes de quaisquer erros do banco de dados em suas respostas. Vulnerabilidades cegas ainda podem ser exploradas para acessar dados não autorizados, mas as técnicas envolvidas são geralmente mais complexas e difíceis de executar.

As seguintes técnicas podem ser usadas para explorar vulnerabilidades de injeção cega de SQL, dependendo da natureza da vulnerabilidade e do banco de dados envolvido:

  • Você pode alterar a lógica da consulta para acionar uma diferença detectável na resposta do aplicativo, dependendo da veracidade de uma única condição. Isso pode envolver a inserção de uma nova condição em alguma lógica booleana ou o acionamento condicional de um erro, como uma divisão por zero.
  • Você pode acionar condicionalmente um atraso no processamento da consulta. Isso permite inferir a veracidade da condição com base no tempo que o aplicativo leva para responder.
  • Você pode acionar uma interação de rede fora de banda usando técnicas OAST. Essa técnica é extremamente poderosa e funciona em situações em que as outras técnicas não funcionam. Muitas vezes, você pode exfiltrar dados diretamente pelo canal fora de banda. Por exemplo, você pode inserir os dados em uma pesquisa de DNS para um domínio que você controla.

Ler mais

Injeção de SQL de segunda ordem

A injeção de SQL de primeira ordem ocorre quando o aplicativo processa a entrada do usuário de uma solicitação HTTP e incorpora a entrada em uma consulta SQL de maneira insegura.

A injeção de SQL de segunda ordem ocorre quando o aplicativo recebe a entrada do usuário de uma solicitação HTTP e a armazena para uso futuro. Isso geralmente é feito colocando a entrada em um banco de dados, mas nenhuma vulnerabilidade ocorre no ponto onde os dados são armazenados. Posteriormente, ao processar uma solicitação HTTP diferente, o aplicativo recupera os dados armazenados e os incorpora a uma consulta SQL de forma insegura. Por esse motivo, a injeção de SQL de segunda ordem também é conhecida como injeção de SQL armazenada.

A injeção de SQL de segunda ordem geralmente ocorre em situações em que os desenvolvedores estão cientes das vulnerabilidades de injeção de SQL e, portanto, lidam com segurança com o posicionamento inicial da entrada no banco de dados. Quando os dados são processados ​​posteriormente, eles são considerados seguros, pois foram previamente inseridos com segurança no banco de dados. Nesse ponto, os dados são manipulados de forma insegura, pois o desenvolvedor os considera, erroneamente, confiáveis.

Examinando o banco de dados

Alguns recursos principais da linguagem SQL são implementados da mesma forma em plataformas de banco de dados populares, e muitas maneiras de detectar e explorar vulnerabilidades de injeção de SQL funcionam de forma idêntica em diferentes tipos de banco de dados.

No entanto, também existem muitas diferenças entre bancos de dados comuns. Isso significa que algumas técnicas para detectar e explorar injeção de SQL funcionam de forma diferente em diferentes plataformas. Por exemplo:

  • Sintaxe para concatenação de strings.
  • Comentários.
  • Consultas em lote (ou empilhadas).
  • APIs específicas da plataforma.
  • Mensagens de erro.
  • Após identificar uma vulnerabilidade de injeção de SQL, geralmente é útil obter informações sobre o banco de dados. Essas informações podem ajudar você a explorar a vulnerabilidade.
  • Você pode consultar os detalhes da versão do banco de dados. Métodos diferentes funcionam para diferentes tipos de banco de dados. Isso significa que, se você encontrar um método específico que funcione, poderá inferir o tipo de banco de dados. Por exemplo, no Oracle, você pode executar:SELECT * FROM v$version
  • Você também pode identificar quais tabelas de banco de dados existem e as colunas que elas contêm. Por exemplo, na maioria dos bancos de dados, você pode executar a seguinte consulta para listar as tabelas:SELECT * FROM information_schema.tables
  • Ler mais
  • Examinando o banco de dados em ataques de injeção de SQL
  • Folha de dicas de injeção de SQL
  • Injeção de SQL em diferentes contextos
  • Nos laboratórios anteriores, você usou a string de consulta para injetar seu payload SQL malicioso. No entanto, você pode realizar ataques de injeção de SQL usando qualquer entrada controlável que seja processada como uma consulta SQL pelo aplicativo. Por exemplo, alguns sites recebem entradas em formato JSON ou XML e as usam para consultar o banco de dados.
  • Esses diferentes formatos podem fornecer diferentes maneiras de ofuscar ataques que, de outra forma, seriam bloqueados por WAFs e outros mecanismos de defesa. Implementações fracas frequentemente procuram palavras-chave comuns de injeção de SQL na solicitação, portanto, você pode contornar esses filtros codificando ou escapando caracteres nas palavras-chave proibidas. Por exemplo, a injeção de SQL baseada em XML a seguir usa uma sequência de escape XML para codificar o Scaractere em SELECT:<stockCheck> <productId>123</productId> <storeId>999 &#x53;ELECT * FROM information_schema.tables</storeId> </stockCheck>
  • Isso será decodificado no lado do servidor antes de ser passado ao interpretador SQL.

Como evitar injeção de SQL

Você pode evitar a maioria das instâncias de injeção de SQL usando consultas parametrizadas em vez de concatenação de strings dentro da consulta. Essas consultas parametrizadas também são conhecidas como “instruções preparadas”.

O código a seguir é vulnerável à injeção de SQL porque a entrada do usuário é concatenada diretamente na consulta:String query = "SELECT * FROM products WHERE category = '"+ input + "'"; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query);

Você pode reescrever este código de uma forma que impeça que a entrada do usuário interfira na estrutura da consulta:PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?"); statement.setString(1, input); ResultSet resultSet = statement.executeQuery();

Você pode usar consultas parametrizadas para qualquer situação em que entradas não confiáveis ​​apareçam como dados dentro da consulta, incluindo a WHEREcláusula e os valores em uma instrução INSERTOR UPDATE. Elas não podem ser usadas para lidar com entradas não confiáveis ​​em outras partes da consulta, como nomes de tabelas ou colunas, ou na ORDER BYcláusula. A funcionalidade do aplicativo que coloca dados não confiáveis ​​nessas partes da consulta precisa adotar uma abordagem diferente, como:

  • Valores de entrada permitidos na lista de permissões.
  • Usando lógica diferente para entregar o comportamento necessário.

Para que uma consulta parametrizada seja eficaz na prevenção de injeção de SQL, a string usada na consulta deve ser sempre uma constante codificada. Ela nunca deve conter dados variáveis ​​de nenhuma origem. Não caia na tentação de decidir caso a caso se um dado é confiável e continue usando a concatenação de strings na consulta para os casos considerados seguros. É fácil cometer erros sobre a possível origem dos dados ou que alterações em outro código contaminem dados confiáveis.

Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *