velhas falhas, novas técnicas- error based sql injection

9
Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 1 Artigos Velhas falhas, novas técnicas: Error Based SQL Injection Por Ulisses Castro, Conviso Security Labs

Upload: conviso-application-security

Post on 23-Jun-2015

928 views

Category:

Documents


1 download

DESCRIPTION

Todos que já buscaram saber como funcionam os ataques de SQL Injection sabem que é uma técnica antiga, porém sempre é bom ver novas ideias surgindo que acabam servindo para ampliar as possibilidades. Quero compartilhar aqui algumas técnicas não convencionais de extração de dados que normalmente são utilizadas por "seres humanos", mas porque dizer assim? Por mais acostumado a automatizar tudo utilizando as melhores e mais variadas ferramentas para pentest, você não pode esquecer que em algumas das muitas situações encontradas durante o processo, é manualmente e com aquele pensamento "fora da caixa" que vai conseguir um resultado inesperado e diferenciado de qualquer outra abordagem similar no mercado. Por isso venho aqui compartilhar uma técnica semelhante a utilizada no MS-SQL Server que é bem conhecida para quem tem experiência em ataques neste tipo de banco de dados, entretanto pouco conhecida e utilizada em outros, em específico MySQL, Oracle, PostgreSQL e SyBase que é o Error Based Blind SQL Injection, nada mais do que a extração de dados baseada em erro.Ferramentas fechadas de renome e também aquelas que tem seu código fonte aberto não abordam tal técnica, perdendo uma grande gama de possibilidades e acabam não suprindo um gap que nós pentesters encontramos. Apesar de não abordar neste artigo especificamente como utilizá-la em conjunto com outras técnicas para bypass em Web Application Firewalls (WAFs), deixo aqui algumas ideias que passam batido em muitos WAFs como HPP em conjunto com SQL Injection e existem até aqueles que deixam passar SQL Injection com erros boleanos pois na assinatura só conseguem se defender quando encontrarm o famoso UNION na URL, fica aqui um gancho para uma próxima pesquisa.

TRANSCRIPT

Page 1: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 1

Artigos

Velhas falhas, novas técnicas: Error Based SQL Injection

Por Ulisses Castro, Conviso Security Labs

Page 2: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 2

Velhas falhas, novas técnicas: Error Based SQL Injection

Por Ulisses Castro | Conviso Security Labs

Todos que já buscaram saber como funcionam os ataques de SQL Injection

sabem que é uma técnica antiga, porém sempre é bom ver novas ideias surgindo

que acabam servindo para ampliar as possibilidades. Quero compartilhar aqui

algumas técnicas não convencionais de extração de dados que normalmente são

utilizadas por "seres humanos", mas porque dizer assim?

Por mais acostumado a automatizar tudo utilizando as melhores e mais variadas

ferramentas para pentest, você não pode esquecer que em algumas das muitas

situações encontradas durante o processo, é manualmente e com aquele

pensamento "fora da caixa" que vai conseguir um resultado inesperado e

diferenciado de qualquer outra abordagem similar no mercado.

Por isso venho aqui compartilhar uma técnica semelhante a utilizada no MS-SQL

Server que é bem conhecida para quem tem experiência em ataques neste tipo

de banco de dados, entretanto pouco conhecida e utilizada em outros, em

específico MySQL, Oracle, PostgreSQL e SyBase que é o Error Based Blind SQL

Injection, nada mais do que a extração de dados baseada em erro.

Ferramentas fechadas de renome e também aquelas que tem seu código fonte

aberto não abordam tal técnica, perdendo uma grande gama de possibilidades e

acabam não suprindo um gap que nós pentesters encontramos. Apesar de não

abordar neste artigo especificamente como utilizá-la em conjunto com outras

técnicas para bypass em Web Application Firewalls (WAFs), deixo aqui algumas

ideias que passam batido em muitos WAFs como HPP em conjunto com SQL

Injection e existem até aqueles que deixam passar SQL Injection com erros

boleanos pois na assinatura só conseguem se defender quando encontrarm o

famoso UNION na URL, fica aqui um gancho para uma próxima pesquisa.

Page 3: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 3

Introdução

Partindo do princípio que o leitor sabe do que se trata um SQL Injection, vamos

deixar claro as seguintes técnicas de maneira resumida:

Union Inband SQL Injection: Técnica onde ao injetar códigos SQL através de uma aplicação, buscamos utilizar a função UNION em conjunto com operadores boleanos para imprimir os dados solicitados na própria página da aplicação.

Blind SQL Injection: Diversas formas diferentes, basicamente utilizando comparações boleanas em conjunto com funções de string do banco de dados, forçamos um verdadeiro ou falso na aplicação montando corretamente ou não a página.

Error Based Blind SQL Injection: Este tipo ataque, o qual vou abordar neste

artigo, é exatamente o tipo que é pouco abordado em ferramentas, onde muitas vezes não conseguimos trazer os dados utilizando o UNION, mas sim forçar que algum erro seja impresso na página,.

Sendo assim existem algumas técnicas para extrair os dados destas mensagens.

Importante frisar que as demonstradas utilizando este tipo de ataque podem

facilmente ser adaptadas para o Blind SQL Injection e também o conhecido Time

Based SQL Injection, que se baseia no tempo em que é retornada determinada

consulta sem enxergar absolutamente nada na interface da aplicação.

Error Based Blind SQL Injection, como funciona?

MySQLVamos ver como poderíamos forçar um erro boleano no MySQL e extrair dados do

mesmo? O pesquisador Dmitry Evteev, apresentou uma técnica muito interessante

utilizando a função ExtractValue() do mysql versão 5.1 ou superior para demonstrar

como extrair dados. No console do MySQL podemos ver o que ocorre ao forçar

um erro utilizando a função apontada, repare que não é utilizado UNION, conforme

apresentado na imagem abaixo.

Page 4: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 4

Esta abordagem é excelente, porém só conseguimos extrair os dados em

versões 5.1 ou mais recentes, a quantidade de dados extraída é limitada a 31

bytes e ainda alguns casos dependemos de um UNION o que é péssimo

frente a defesas como WAFs. Abaixo, um exemplo demonstrando a limitação

dos 31 bytes:

Para as limitações citadas existem diversas formas de amenizar estas

dificuldades, primeiro é preciso eliminar a dependência de versão. Abaixo um

insight feito por Qwazar que demonstra como é possível realizar esta técnica

aplicada para versões do MySQL 4, 5.0, 5.1 e superiores. Tal abordagem além

de mitigar a limitação da versão, amplia a quantidade de bytes extraídos

passando de 31 para 64 bytes e mantém a mesma lógica demonstrada

acima:

Porém nos traz mais uma desvantagem, neste caso devido a função rand(),

não existe 100% de chance de retorno, ou seja, as vezes o resultado pode vir

e as vezes não. Isso é péssimo, principalmente em casos onde escrevemos

um script para automatizar mas como sempre existe uma solução, abaixo

montei uma versão sem utilizar UNION e mantendo 99% de retorno do

resultado. Não sou DBA e nem mesmo ultra expert em SQL, assim acredito

que alguém com mais experiência possa ajudar a montar um consulta um

pouco menor, mas a syntax ficou assim (seguindo o mesmo exemplo acima):

select '1 ' and if(row(0,0)> (select + count(*), concat((select concat_ws

(0x3a,user,password) from mysql.user limit 1), 0x3a, floor(rand()*2)) x from

mysql.user group by x limit 1),1,if(row (0,0)> (select + count(*),concat((select

concat_ws(0x3a,user,password) from mysql.user limit 1),0x3a,floor(rand()*2)) x from mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*),concat((select

concat_ws(0x3a,user,password) from mysql.user limit 1),0x3a,floor(rand()*2)) x from

mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*),concat((select concat_ws(0x3a,user,password) from mysql.user limit 1),0x3a,floor(rand()*2)) x from

mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*),concat((select

concat_ws(0x3a,user,password) from mysql.user limit 1),0x3a,floor(rand()*2)) x from mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*),concat((select

concat_ws(0x3a,user,password) from mysql.user limit 1),0x3a,floor(rand()*2)) x from

mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*), concat((select

concat_ws(0x3a,user,password) from mysql.user limit 1), 0x3a, floor(rand()*2)) x from mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*),concat((select

concat_ws(0x3a,user,password) from mysql.user limit 1),0x3a,floor(rand()*2)) x from

mysql.user group by x limit 1),1,if(row(0,0)>(select + count(*),concat((select concat_ws(0x3a,user,password) from mysql.user limit 1), 0x3a,floor(rand()*2)) x

from mysql.user group by x limit 1),1,(select 1 and 1=1))))))))));

Page 5: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 5

Veja que o resultado apresentado na imagem abaixo não vem truncado em 31

bytes e conseguimos ver a hash completamente, pois conseguimos trazer 64

bytes. Essa talvez não seja nem de perto a melhor solução e seria preciso

estudar um pouco mais algumas formas de melhorar os resultados.

Com a utilização desta técnica, em conjunto com outras funções específicas

do MySQL, é possível ampliar ainda mais extração de dados. Utilizando a

função compress() com a biblioteca zlib podemos compactar o resultado,

conforme apresentado abaixo.

Com isso, é possível diminuir o tamanho do resultado, o que nos testes que

realizei chegaram a 50% de taxa na compressão. Porém, a desvantagem é

que não seria possível utilizar técnica de Verdadeiro/Falso para extrair

caractere por caractere, pois o tipo de dado de retorno impede que isso

aconteça.

Porém a solução é simples, com a função hex() conseguimos transformar todo

o resultado em hexadecimal, e com esta saída não só podemos transportar

qualquer tipo de dados como ainda facilita a comparação Verdadeiro/Falso em

casos de Blind SQL Injection, e pode preparar a consulta para trazer um "tira"

única em hexadecimal de todos os dados solicitados independente do

tamanho.

Page 6: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 6

A única desvantagem perceptível é que o processamento do banco de dados

será elevado em caso de automatização, mas isso pode ser ajustado através

de delays e timers. Na prática para extrair os dados, seria necessário

"caminhar" pela tira em hexadecimal, extraindo o resultado de 64 em 64 bytes

ou 32 em 32 bytes dependento da técnica, utilizando funções específicas para

lidar com strings. Na prática ficaria como na imagem abaixo:

E para potencializar tudo isto seria possível ainda utilizar "sub-querys" e trazer

muitos dados com pouquíssimos "hits" no Servidor Web, técnica que

demonstrei no OWASP AppSec Brasil do ano passado. Porém nem todas as

empresas utilizam MySQL e é preciso estar preparado para encontrar os mais

diversos tipos pela frente. Acima demonstrei como é feito com MySQL, porém

cada um possui sua limitação e também vantagens, o que nos traz novas

possibilidades a cada abordagem.

Aplicação em outras bases

Abaixo algumas idéias menos elaboradas do que esta feita no MySQL, porém

mostrando a pontinha do iceberg e um caminho para aplicar a mesma técnica

em diferentes cenários.

MSSQL Server / SybaseNão é nada novo, a maioria das técnicas de SQL Injection demonstradas em

diversos forums, how-tos, listas de discussão, demonstram esta técnica que

força a conversão no tipo de dado para demonstrar o erro, no caso do

MSSQL é possível trazer aproximadamente 1024 bytes e no Sybase a técnica

é a mesma.

Page 7: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 7

PostreSQLSemelhante ao MSSQL/Sybase, porém utilizando a função CAST():

E seguindo a mesma linha de raciocínio aplicada no MySQL:

OracleDemonstrando esta técnica utilizando Oracle 9.0 ou superior, é possível extrair

até 214 bytes de uma mensagem de erro no Oracle usando a função XMLType

() em conjunto com outras para tratamento de string, seguindo lógica

semelhante a demonstrada com o MySQL, transforma a consulta em

hexadecimal, usa substr() para cortar a "tira" e trazer os resultados em partes.

E ainda podemos utilizar um truque para trazer versão em uma única linha,

isso porque o Oracle não possui offset ou limit:

SELECT banner FROM(SELECT banner,rownum rnum FROM v$version a)WHERE rnum=1;

Usar XMLType() para mostrar a versão na saída de erro, para isto foi

necessário utilizar a função REPLACE() e substituir os espaços por

"_"(underline). Repare que a todo momento utilizo a função CHR() visando

evitar qualquer problema com caracteres de "'"(aspas simples).

SELECT XMLTYPE(CHR(60)||CHR(58)||(SELECT REPLACE((SELECT banner FROM(SELECT banner,rownum rnum FROM v$version a)WHERE rnum=1),CHR(32),CHR(95))FROM dual)||CHR(62))FROM dual;

Page 8: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 8

Abaixo uma versão mais apurada para burlar os problemas de tipos de dados,

assim como replicar técnica semelhante à aplicada ao MySQL, utilizando

conversão para hexa e removendo a função REPLACE() não precisamos dela

já que estamos convertendo para hexadecimal.

SELECT UPPER(XMLTYPE(CHR(60)||CHR(58)||(SELECT RAWTOHEX((SELECT banner FROM(SELECT banner,rownum rnum FROM v$version a)WHERE rnum=1))FROM dual)||CHR(62)))FROM dual;

E finalmente a versão para ser utilizada em um Error Based Blind SQL Injection

utilizando operador lógico simulando um ataque.

SELECT 1 FROM dual WHERE 1=1 AND(1)=(SELECT UPPER(XMLTYPE(CHR(60)||CHR(58)||(SELECT RAWTOHEX((SELECT banner FROM(SELECT banner,rownum rnum FROM v$version a)WHERE rnum=1))FROM dual)||CHR(62)))FROM dual);

Existem diferentes maneiras de se chegar ao mesmo objetivo, com um

conhecimento maior em determinado banco de dados e mais pesquisas, com

certeza é possível chegar a um resultado mais apurado, lembrando que em

todos os casos sempre pensei em não utilizar o UNION para tentar evitar um

possível match de assinatura com WAFs, assim como a utilização de função

para representar caracteres ascii na consulta e evitar enviá-los através de URL.

Page 9: Velhas falhas, novas técnicas- Error Based SQL Injection

Conviso IT Security | Artigos | Velhas falhas, novas técnicas: Error Based SQL Injection 9

Conclusão

SQL Injection é uma técnica que por mais antiga que seja a cada dia evolui,

seja com lançamento de novas versões com novas funções, ou fazendo uma

releitura de técnicas já conhecidas e aprimorando sempre é possível

demonstrar algo novo.

E como sou um viciado convicto em Python nada melhor do que escrever

scripts em python usando threads somado a técnicas novas, é sempre

diversão garantida. Abaixo um screen shot do video demonstrando na prática

um script que aplica a técnica acima, atacando um banco de dados MySQL,

disponível na íntegra no canal da Conviso IT Security no YouTube, em http://

www.youtube.com/ConvisoITSecurity.

Em um futuro próximo a Conviso IT Security estará disponibilizando em

formato Open Source algumas ferramentas criadas em laboratório, fique de

olho! ;)

Referências

http://www.owasp.org/index.php/SQL_Injection

http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

http://www.owasp.org/index.php/AppSec_Brasil_2009_%28pt-br%29#tab=Arquivos_das_Apresenta.C3.A7.C3.B5es

https://forum.antichat.ru/printthread.php?t=119047&page=2&pp=10

http://ptresearch.blogspot.com/2010/01/methods-of-quick-exploitation-of-blind_25.html

http://qwazar.ru/?p=7

Sobre o Autor

Ulisses Castro

Atuando há muitos anos com IT Security,

iniciou suas atividades no Conviso

Security Labs em 2008, contribuindo no

desenvolvimento de novas ferramentas,

análise de malware, criação de exploits e

payloads para testes de segurança.

Especializado em testes de intrusão e

análise de vulnerabilidades, trabalhou

como consultor e administrador de

sistemas operacionais Linux/Unix. É

palestrante em eventos internacionais

como FISL e OWASP AppSec Brasil,

contribui e participa ativamente em

projetos com ênfase em software livre

como Debian, Metasploit e OWASP.