SQL INJECTION Baseado em UNION
caso nao tenha visto o meu post sobre SQL injection, recomendo que veja para entender 100% o conteudo desse post. https://www.tabnews.com.br/LIGHTdev4687/sql-injection
O QUE É UM ATAQUE DE SQL INJECTION BASEADO EM UNION? O SQLI baseado em UNION pode acontecer quando a aplicação é vulneravel e os resultados da requisição são retornados na aplicação, assim, usando a palavra chave UNION podemos fazer mais de um SELECT dentro da consulta, e anexar os resultados a consulta original do sistema no banco de dados.
assim que uma consulta com UNION se parece:
SELECT a,b FROM table1 UNION SELECT c,d FROM table2
essa unica consulta retornara um unico conjunto de resultados com 2 tabelas(table1 e table2) com as colunas a e b, c e d respectivamente.
para que a palavra chave UNION funcione em uma requisição é nessesario que dois requisitos principais sejam atendidos:
- as consultas devem ter o mesmo numero de colunas note que na requisição acima é solicitado a e b de table1 e c e d de table2, no caso 2 colunas por requisição, respeitando a esse requisito.
- os tipos de dados das colunas devem ser compativeis entre as consultas se a coluna a for do tipo string, a coluna c tambem deve ser desse tipo, o mesmo se aplicaria á b e d, tendo que ser de um mesmo tipo.
então, poderiamos dizer que antes de executarmos um ataque UNION, deveremos descobrir:
- quantas colunas estão sendo retornadas na consulta original.
- quais são os tipos de dados respectivos para cada coluna, para correspondermos na UNION injetada.
para testarmos com exatidão quantas colunas estão sendo utilizadas da requisição original deveremos injetar o seguinte codigo na requisição:
' UNION SELECT NULL--
o que faria a requisição ficar assim:
SELECT coluna1,coluna2 FROM table1 UNION SELECT NULL--
como podemos ver, a requisição original solicita 2 colunas de table1, e a solicitação injetada UNION solicita uma coluna da tabela, e ja que NULL é conversivel para qualquer tipo de dado, essa tecnica é usada para determinar o numero de tabelas usadas na requisição original independente do tipo. como na requisição original 2 tabelas são solicitadas e apenas 1 tabela na UNION injetada, essa solicitação nos retornara um erro(generico ou de server), assim sabemos que mais de uma coluna é usada na requisição original.
assim que colocarmos o numero corretos de NULL para coresponder ao numero de tabelas, vamos ter como resposta simplismente espaços em brancos depois da resposta original ou alguma resposta que nao cause um erro.
a injeção correta seria assim:
SELECT coluna1,coluna2 FROM table1 UNION SELECT NULL,NULL--
tendo constatado o numero de colunas, o proximo passo é testar qual o tipo de dado de cada um, ou uma delas que tenha o tipo de dado que voce deseja obter da injecao.
para isso, trocaremos o NULL por um tipo de dado mais expecifico,vamos tentar com strig na primeira coluna injetada(NULL).
SELECT coluna1,coluna2 FROM table1 UNION SELECT 'abc',NULL--
vamos considerar nesse exemplo que tabela1 é do tipo int, e tabela2 do tipo string.
como sabemos que a primeira coluna da consulta original é do tipo int, ocorrera um erro por diferenças de tipo, o que nos retornara um erro(generico ou de server), mas principalmente, vamos saber que a primeira tabela nao é do tipo string.
ok, vamos tentar colocar uma tabela do tipo string na segunda tabela da injeçao(no lugar no segundo NULL). e voltaremos com o null na primeira tabela da injeção.
SELECT coluna1,coluna2 FROM table1 UNION SELECT NULL,'abc'--
pela segunda coluna da tabela original ser do tipo string,nao ocorrera erro por diferença de tipo. o que nos retornara na resposta um 'abc' no lugar da resposta original, ou logo em seguida.
sabendo que a primeira coluna não é do tipo string, presumivelmente se tentaria o tipo int,que nesse caso, estaria certo.
OK,MAS COMO ISSO É UTILIZADO NA PRATICA POR ATACANTES?
para entendermos o quão grave é essa vulnerabilidade, vamos seguir com o seguinte exemplo:
^ esse site de compras online separa seus itens por categorias, vamos clicar em uma para ver o que acontece:
como podemos ver, a URL mostra que category= a categoria que clicamos, e no site, de acordo com isso, é devolvido uma resposta visual, isso é perfeito para testarmos uma SQL injection baseado em UNION.
- primeira coisa: saber quantas colunas são usadas na consulta original! para isso vamos fazer o processo de testar com NULL(s) na requisição injetada o numero de colunas usadas.
apos testarmos o numero de NULLs por tentativa e erro, vamos ver que o numero de colunas usadas é 2.
- segunda coisa: saber quais colunas tem o tipo que precisamos na exploração! para isso, vamos trocar cada NULL para o tipo de dado que pretendemos achar. no caso vamos procurar tabelas do tipo string. por sorte(ou eu tentando simplificar a explicação) as duas são do tipo string, o que nos leva para a parte da exploração.
uma coisa que qualquer atacante tentaria com essa vulnerabiliade em mãos, é roubar os dados da conta de outros usuarios(nome,senha,email,telefone,cpf,dados do cartão de credito e etc...)
a seguinte injeção sql pode nos retornar táis informações(nome e senha no caso)
'+UNION+SELECT+username,+password+FROM+users--
veja que usamos username e password, nomes que presumimos que exista no banco de dados para que nos retorne os dados do usuario. users tambem é um nome de table generico que chutamos que exista.
se tudo der certo,teremos o username e password de todos os usuarios no banco de dados.
lembrando que esse nomes das categorias,colunas e tables podem não existir no banco, mas testar nomes padroes e comuns para a arquitetura do banco de dados, é possivel e muito mais facil usando alguma ferramenta pra isso com o auxilio de wordlists.
acho que é isso:)
qual pratica recomendada para se proteger nesse caso?