Fuzzing a una aplicación con zzuf

Introducción: ¿por qué fuzzing?

Cuando nos encontramos haciendo tareas de ingeniería inversa a una aplicación, una de las tareas más monótonas es la de enviar stuffcosas«) a un punto de entrada de la aplicación para ver cómo responde. En función de nuestro objetivo (descubrir buffer overflow, format string…), el tipo de stuff que enviemos variará, no sólo en su contenido si no también en su cantidad, sobre todo si lo que buscamos es provocar un buffer overflow. Y cuando hablamos de cantidad, lo ideal es hacer fuzzing en lugar de hacerlo con peticiones manuales.

En el caso de los desbordamientos, más que el tipo de contenido lo que se busca es la cantidad, y aquí tenemos varias opciones de enviar «cosas» a la aplicación; de forma manual, mediante ejecución de instrucciones Python / Perl desde la consola, creándonos nuestro propio script o utilizar herramientas ya desarrolladas para este tipo de tareas; fuzzers.

En este artículo veremos distintas opciones, para finalmente presentar y ver algunos ejemplos de zzuf, el fuzzer del que vamos a hablar en este post.

Escenario

Para explicar el funcionamiento de un fuzzer, y de zzuf concretamente hemos preparado el siguiente escenario; una aplicación remota vulnerable a buffer overlflow (basado en stack), accesible a través del puerto TCP/9999.

Ese puerto a la escucha es nuestro único punto de entrada. Podríamos escanear el puerto, descubrir versión del servicio y buscar si hay alguna vulnerabilidad desconocida. En caso negativo, no nos queda otra que enviar cosas al puerto y ver cómo responde la aplicación.

Fuzzing - Netcat a vulnserver

En este caso, haciendo netcat al puerto conseguimos acceso a la aplicación, donde nos indica que podemos obtener ayuda escribiendo el comando HELP.

Peticiones manuales a la aplicación

Obviamente nuestra intención es otra, es encontrar qué tipo de información tenemos que enviarle y en qué cantidad. La explotación de la vulnerabilidad de buffer overflow no entra en el contexto de este artículo, lo explicaremos más adelante en otro, pero se puede ver marcado en amarillo una serie de comandos de la aplicación. Estos comandos son los usaremos para enviar nuestro stuff e intentar provocar el BO (buffer overflow).

Fuzzing - Netcat a vulnserver

Como decíamos en la introducción al artículo, podemos hacer peticiones manuales. En la imagen anterior al comando HELP le hemos añadido una serie de caracteres, primero dígitos y a continuación acompañados de varios caracteres «A«. La respuesta de la aplicación es que ese comando no está implementado. Podríamos seguir probando con más cantidad, con otros comandos, pero como os podéis imaginar esto llega a ser bastante tedioso y monótono si lo hacemos manualmente.

Más cantidad con Python / Perl

Para facilitar esta introducción de información a la aplicación, para forzar algún tipo de error que provoque por ejemplo en crash en la misma, podemos hacer uso de lenguajes como Python o Perl desde la propia consola. En nuestro caso estamos utilizando Kali como máquina «atacante».

Así que una forma muy simple podemos mandar más cantidad de información al puerto TCP/9999 de la aplicación. Supongamos que queremos enviarle 200 caracteres «A». En lugar de escribirlos, podemos hacer uso de Python para generar esos caracteres y la salida enviarla con netcat al puerto de la aplicación.

Con un simple comando «echo» podríamos enviar la salida de éste a «netcat», pero tendríamos el mismo problema:

echo «HELP 1234567890AAAAAAAA» | nc 192.168.10.145 9999

Sin embargo podemos concatenar la salida de una instrucción Python al comando «echo».

Fuzzing - Python y netcatComo se puede ver en la imagen, enviar una gran cantidad de datos a una aplicación remota con Python es realmente sencillo. En el último ejemplo hemos enviado 5000 caracteres «A» y podemos observar un comportamiento distinto, en cuanto a respuesta de la aplicación, que cuando se enviaron 50 o 500 caracteres «A». Interesante.

Utilizando un fuzzer: zzuf

Por último, veamos cómo hacerlo con el protagonista real de este artículo, un fuzzer llamado zzuf, que nos va a ayudar en nuestra labor a la hora de hacer fuzzing a la aplicación y que además altera de forma aleatoria el contenido de lo que enviamos. Recordad que en ocasiones no es tan importante la cantidad si no la calidad de lo que se envía.

De hecho vamos a utilizar zzuf justo para eso, para alterar de forma aleatoria la información que vamos a enviar, ya que hemos visto que generar contenido es muy sencillo con Python o Perl.

Así que, de forma sencilla, vamos a generar un fichero txt con Python que contendrá el comando «HELP » seguido de una gran cantidad de caracteres «A», por ejemplo 500.

Fuzzing - Python

Ya tenemos un fichero llamado fuzz.txt.

Ahora con zzuf lo que vamos a hacer es alterar aleatoriamente el contenido del fichero, veamos un ejemplo:

Fuzzing - zzuf

En la imagen anterior, en la primera ejecución vemos cómo altera aleatoriamente la salida del «cat» del fichero. Pero atención, hay un problema y es que también ha alterado el tercer byte de nuestro fichero, dejando el comando «HELP» en «HENP«, lo cual no nos interesa.

Zzuf tiene esto en cuenta y permite con el parámetro -b indicar a partir de qué byte empieza a alterar. En la segunda ejecución de zzuf hemos indicado -b6- para que empiece a partir del sexto byte, para que no modifique la palabra HELP.

También podemos indicar el ratio de modificación del contenido. Por ejemplo, si queremos que modifique el 50% del contenido haremos uso del parámetro -r de la siguiente forma:

zzuf -b6- -r0.5 cat fuzz.txt

Hasta aquí este artículo sobre fuzzing con zzuf. Espero que os haya resultado útil y entendáis la facilidad con la que se puede generar stuff para enviarla a una aplicación remota, siempre teniendo en cuenta en qué momento nos interesa cantidad o calidad (zzuf).

¡Hasta la próxima!

Miguel A. Arroyo
@miguel_arroyo76