Universidade Estadual de Mato Grosso do Sul Curso de Computação, Licenciatura Banco de Dados SQL injection '1 = 1 Prof. José Gonçalves Dias Neto [email protected] SQL Injection - Introdução Injeção de SQL, ou SQL embutido, é uma vulnerabilidade existente em bancos de dados, utilizadores da linguagem SQL, consistindo em uma técnica que se aproveita de sentenças de SQL previamente existentes nesses bancos de dados e as “amplia” ou “danifica” de forma que o atacante consiga obter dados que não estariam disponíveis na sentença original, ou simplesmente que seja capaz de executar comandos danosos à base de dados existente. Assim o atacante consegue inserir uma sentença SQL dentro de outra previamente existente. Isso é possível quando a aplicação é capaz de pegar entradas do usuário e combinar com parâmetros estáticos para montar uma consulta SQL. SQL Injection - Ataque Construímos um banco de dados fictício o qual chamamos de SQLINJECTION. Neste construímos unicamente uma tabela a partir do seguinte comando SQL. CREATE TABLE LOGIN( user VARCHAR(10) NOT NULL PRIMARY KEY, senha VARCHAR(10) NOT NULL); Feito isto, abastecemos com diversas entradas a tabela criada. Obviamente poderíamos listar todos os usuários inseridos na respectiva tabela a partir do seguinte comando. SELECT * FROM LOGIN; SQL Injection - Ataque Uma aplicação faria a busca de um login válido desta forma: SELECT * FROM LOGIN WHERE user = 'campo_nome' AND senha = 'campo_senha'; Onde campo_nome e campo_senha, sejam entradas passadas pelo usuário. Neste caso, qualquer nome de usuário que não pertença à tabela não retornará elementos, o mesmo acontece com a senha e com a junção user + senha. SQL Injection - Ataque Através da técnica de SQL injection, podemos modificar o comportamento de uma sentença e trabalhar com seus resultados. O primeiro teste básico que podemos fazer, é causar uma quebra ou parada inesperada na sentença através da utilização do caractere especial ; (ponto e virgula), mas para isso também precisaremos trabalhar com o caractere aspa simples. Faremos o seguinte, no local do campo_nome inseriremos apenas mais uma aspa simples entre as duas, e após isto um ponto e virgula, ficando a sentença da seguinte forma: SELECT * FROM LOGIN WHERE user = '';' AND senha = 'campo_senha'; SQL Injection - Ataque Isto causará a execução da sentença unicamente até a comparação user = '' pois após isto o ponto-e-vírgula indicará o término da sentença. Obviamente não foi mérito apenas do ponto-e-virgula, o qual foi responsável unicamente por identificar o término da sentença, porém se o mesmo estivesse sozinho dentro das aspas inicialmente existentes, permitiria que TODA a sentença fosse executada, pois as aspas indicariam que ele não se trataria naquele momento de um caractere especial de comando, mas sim de um caractere de texto informado pelo usuário. Através da utilização consciente da aspa, podemos manipular a sentença, indicando o que é ou não um caractere de texto ou de comando, facilitando a injeção de código malicioso onde antes era possível apenas a inserção de texto simples. SQL Injection - Ataque Alterando a sentença inicial com a inserção de uma aspa simples entre as duas existentes do usuário, verificamos que o SGBD não identifica o final da sentença, permitindo ao usuário inserir mais e mais caracteres. Isto se deve pois o SGBD aguarda o caractere de ponto e vírgula, pois o que está contido na sentença está agora sendo tratado como texto e não comando. SELECT * FROM LOGIN WHERE user = ''' AND senha = 'campo_senha'; SQL Injection - Ataque A partir desta informação, podemos alterar a sentença de forma a transformar tudo o que existe entre o primeiro dado informado pelo usuário (campo_user) e tudo antes do campo_senha, de modo a serem interpretado como texto. Depois disso, podemos inserir uma sentença que sabidamente retornará sempre verdadeira fazendo com que haja liberações do SGBD de dados pertencentes à tabela acessada. Assim, uma forma de termos acesso a TODOS os dados da tabela é inserir o seguinte texto dentro de user e senha respectivamente: campo_user → ' campo_senha → '1=1 SQL Injection - Ataque Ficando o comando escrito da seguinte forma: SELECT * FROM LOGIN WHERE user = '''1 AND senha = 'or '1=1'; Para efeito de melhor expressão, o mesmo comando será reescrito com o que será interpretado como texto pelo SBGD com fundo amarelo. SELECT * FROM LOGIN WHERE user = '''1 AND senha = 'or '1=1'; Sentença esta que poderia também ser expressa da seguinte forma: SELECT * FROM LOGIN WHERE user = '''1 AND senha = 1' or '1' = '1'; SQL Injection - Proteção Uma das formas de se proteger deste ataque é efetuar a checagem de campos do tipo string evitando a entradas que contenham os seguintes caracteres especiais: " (aspas duplas) ' (aspas simples) ; (ponto e vírgula) = (sinal de igual) < (sinal de menor que) > (sinal de maior que) ! (ponto de exclamação) -- (dois hifens) # (sustenido ou jogo-da-velha) // (duas barras) Palavras chave devem ser evitadas: - SELECT – INSERT - UPDATE - DELETE – WHERE - JOIN - LEFT - INNER - NOT - IN - LIKE - TRUNCATE- DROP - ALTER - CREATE - DELIMITER *Os 3 últimos indicam início de comentário em alguns bancos) Outra forma, seria criptografar as entradas antes de salvar no banco, e no momento da consulta efetuar a criptografia do conteúdo comparando com a informação criptografada anteriormente. Bibliografia