Creando un fuzzer simple

1. Responsabilidad

El autor declina toda responsabilidad sobre cualquier uso de la información presentada en el mismo. Se trata de una prueba de concepto útil para las pruebas de intrusión, para los pentesters.

2. Introducción

Alguien lanzó el comentario, tras el primer artículo sobre fuerza bruta sobre cómo convertir eso en un fuzzer. Aunque es un ejemplo muy sencillo, tras meditarlo decidí desarrollar el siguiente tutorial.

Utilizaremos, igual que en otros: python (http://www.python.org).
Aunque podríamos emplear la fuerza bruta, dado que esto ya se trató en otro artículo, en este caso haremos un ataque basado en diccionario. El lector podrá así, fácilmente adaptarlo a otros ataques como al del MD5, de hecho, le animo a ello.
Para hacerlo lo más sencillo posible, se trata de probar URLs para ver cuáles existen en el servidor (similar a lo que hace un crawler); pero no debería ser complicado adaptarlo a: pruebas de parámetros, validación de entradas, etc. Y por supuesto no está limitado a aplicaciones o sitios web. Quizá en posteriores entradas lo extienda a algo aplicable en este sentido: pruebas sobre aplicaciones stand-alone en busca de problemas explotables…

Aclaración

Qué no pretende este artículo:

  • Como he comentado otras veces, no, no es un texto dedicado a la programación, ni al estilo programando (para eso existen otros textos). Así que si crees que se puede hacer mejor o más limpio, cualquiera de los pasos, adelante con ello.
  • Sí, existen herramientas para fuzzing sencillas, pero al desarrollar a mano ésta, podrás adaptarla fácilmente a tus necesidades al tiempo que aprendes

4. Prerequisitos

Se presupone unos conocimientos mínimos de programación. Al menos entender las condiciones lógicas, bucles, etc. Unos conocimientos aunque sean básicos del lenguaje http://www.python.org, son recomendables, si bien, no debería ser complicado para el lector, poder adaptar el código a cualquier otro lenguaje con el que se sienta más cómodo, si lo considera necesario.

5. Primeros pasos, definición del algoritmo a crear

Comencemos definiendo qué es un fuzzer, a grosso modo diremos que es un método de pruebas en el que generamos datos aleatorios (o pseudo-aleatorios) y analizaremos las respuestas mediante un sistema que determine si son válidas o no (normalmente llamado: oráculo), para encontrar posibles fallos.

En el campo de la seguridad implica la búsqueda de fallos de seguridad y hoy en día, este tipo de pruebas, es al que se refieren más frecuentemente al utilizar el término fuzzer.
En nuestro caso, generaremos las pruebas pseudo-aleatorias, basándonos en una URL y una lista de palabras. Luego, nuestro oráculo, decidirá si es válida lo que ha encontrado o no, basándonos en la respuesta del servidor (existe la página) y también, posteriormente, en el contenido de dicha página.

En lenguaje natural, el objetivo del algoritmo a crear :
Leeremos una lista de palabras y otra de extensiones posibles y, partiendo de una URL base (objetivo a probar), añadiremos cada una de las palabras combinándolas con las extensiones, y verificaremos si se devuelve alguna página o no.

Empezaremos por cargar la lista de palabras y de extensiones, recorriendo las primeras y para cada una de ellas, las segundas, probando cada combinación posible. Podríamos utilizar métodos HEAD pero, debido a que muchos servidores lo deshabilitan, intentaremos abrir la URL (lo que, desgraciadamente, es más lento).

Comencemos imprimiendo la lista, por pantalla. Inicialmente creamos dos listas: list.txt (diccionario a usar, de ejemplo) y extensions.txt (extensiones posibles). Introducimos valores de prueba, como:
list.txt:

extensions.txt:

Como primera extensión, podemos introducir una línea vacía, para probar sin ninguna extensión. Generamos el código necesario para imprimir la combinación por pantalla:

Obtenemos la siguiente salida:

A continuación, generaremos nuestra función de chequeo sobre una URL. Para ello, utilizaremos el método: code, a partir de la respuesta obtenida por: urlopen, para obtener el código HTTP.
Dado que los errores son los códigos 400 y 500, discriminaremos aquellos resultados que devuelvan un código de respuesta cuyo primer dígito sea un 4.
Asimismo, debido a que la petición puede fallar, gestionaremos la excepción, entendiendo que no existe la URL que estamos probando, en caso de que ésta se dispare. En caso de que ni la excepción ni el código devuelto sea un error consideraremos que esa URL existe.

El resultado dependerá del sitio que estemos probando, podría ser algo como:

* Ojo, estamos lanzando: “número de palabras * número de extensiones” peticiones al servidor web por lo que podríamos disparar numerosas alarmas de detección de intrusión que podrían denegarnos el acceso el sitio o, sobra decir que en caso de no tener permiso, incluso problemas legales.

Para dar un paso más, supongamos que queremos encontrar una cadena determinada en dicha página, añadimos la carga de la página y la búsqueda de dicha cadena (en nuestro ejemplo la palabra “login”):

Y dependiendo de nuestras pruebas, obtendremos algo como:

Partiendo de esta base, es sencillo adaptar el programa para ser usado de manera más cómoda desde línea de comandos, recibiendo por ésta los valores a probar. También modificar el comportamiento para determinar cuándo una URL es válida para nosotros y cuándo no en función a otros parámetros…

6. Sobre el Autor

Jesús Arnáiz es Consultor de Seguridad en Chase The Sun S.L., entre otros ha trabajado en proyectos de auditoría y consultoría de seguridad, pruebas de intrusión/hacking ético, análisis forense y cumplimiento normativo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*