Tutorial de prueba de fuzz (fuzzing)

โšก Resumen inteligente

Las pruebas de fuzzing introducen datos no vรกlidos, inesperados o aleatorios en un programa y observan si se producen fallos, bloqueos o errores de memoria, lo que permite detectar defectos de seguridad que las pruebas funcionales basadas en scripts casi nunca detectan por sรญ solas.

  • ๐Ÿ”˜ Origen: Barton Miller acuรฑรณ el tรฉrmino en la Universidad de Wisconsin-Madison, y las primeras pruebas de fuzzing en 1989 provocaron el fallo de aproximadamente un tercio de las utilidades de UNIX probadas.
  • โ˜‘๏ธ Bucle de seis pasos: Identificar el objetivo, identificar las entradas, generar datos simulados, ejecutar, monitorear el comportamiento y luego registrar cada defecto que aparezca.
  • โœ… Tres estrategias generacionales: Los fuzzers de mutaciรณn distorsionan las muestras vรกlidas, los fuzzers de generaciรณn construyen entradas a partir de un modelo y los fuzzers de protocolo funcionan a partir de una especificaciรณn.
  • ๐Ÿงช Los comentarios recibidos sobre la cobertura cambiaron el panorama: Los motores de bรบsqueda modernos conservan cualquier dato de entrada que llegue al cรณdigo nuevo, lo que permite detectar errores mucho mรกs profundos que los que se encontrarรญan con datos puramente aleatorios.
  • ๐Ÿ› ๏ธ Las herramientas han evolucionado: Peach Fuzzer y WebScarab estรกn archivados, mientras que AFL++, libFuzzer, OSS-Fuzz, boofuzz โ€‹โ€‹y OWASP ZAP son las opciones que se mantienen.
  • โš™๏ธ Lรญmites conocidos: Las pruebas de fuzzing detectan fallos del sistema, no errores lรณgicos, por lo que complementan, en lugar de sustituir, la revisiรณn de cรณdigo y las pruebas de penetraciรณn.

Tutorial de prueba de fuzz (fuzzing)

ยฟQuรฉ es la prueba Fuzz?

Pruebas de fuzzing o fuzzing Fuzz es una tรฉcnica de prueba de software que consiste en introducir datos no vรกlidos o aleatorios (conocidos como FUZZ) en un sistema informรกtico para descubrir errores de codificaciรณn y vulnerabilidades de seguridad. El objetivo de las pruebas Fuzz es insertar datos mediante tรฉcnicas automatizadas o semiautomatizadas y probar el sistema en busca de diversas excepciones, como fallos del sistema o errores en el cรณdigo integrado.

Las pruebas de fuzzing fueron desarrolladas originalmente por Barton Miller en la Universidad de Wisconsin-Madison, quien acuรฑรณ el tรฉrmino despuรฉs de que el ruido de la lรญnea en un enlace de mรณdem provocara el fallo de los programas que estaba utilizando. Sus estudiantes ejecutaron los primeros fuzzers en 1989 y descubrieron que aproximadamente un tercio de las utilidades UNIX a las que apuntaban fallaban o se bloqueaban. Las pruebas de fuzzing son una herramienta para detectar errores de programaciรณn. pruebas de software tรฉcnica, y es un tipo de Pruebas de seguridad.

El diagrama que aparece a continuaciรณn muestra el ciclo bรกsico de pruebas de fuzzing, donde se envรญan datos generados a la aplicaciรณn que se estรก probando y se observa la respuesta.

Flujo de trabajo de las pruebas de fuzzing: un fuzzer genera una entrada mal formada y la introduce en la aplicaciรณn bajo prueba.

ยฟPor quรฉ hacer pruebas Fuzz?

El fuzzing se justifica en un plan de pruebas porque explora entradas para las que nadie pensรณ en escribir un caso de prueba. Las principales razones por las que los equipos lo adoptan se enumeran a continuaciรณn.

  • Las pruebas de fuzzing suelen detectar los fallos y defectos de seguridad mรกs graves, ya que un fallo del sistema es una prueba directa de una ruta de entrada no gestionada correctamente.
  • Las pruebas de fuzz dan un resultado mรกs efectivo cuando se utilizan con Negro Box Pruebas, Pruebas Beta y otros mรฉtodos de depuraciรณn.
  • Las pruebas de fuzzing se utilizan para comprobar la vulnerabilidad del software y son una tรฉcnica de prueba muy rentable porque las entradas se generan automรกticamente en lugar de escribirse manualmente.
  • Las pruebas de fuzzing son una de las tรฉcnicas de prueba de caja negra. Ademรกs, son uno de los mรฉtodos mรกs comunes que utilizan los hackers para encontrar vulnerabilidades en un sistema, por lo que ejecutarlas primero elimina la vรญa de acceso mรกs fรกcil para un atacante.

Tipos de pruebas de fuzzing

Los fuzzers suelen clasificarse segรบn el nivel de conocimiento que poseen sobre el programa que atacan. Cuanto mรกs conocimiento tenga el fuzzer, mรกs podrรก penetrar en el cรณdigo.

Tipo Lo que sabe el fuzzer Uso tรญpico
Fuzzing de caja negra No muestra nada sobre el funcionamiento interno; solo detecta entradas y salidas. Pruebas rรกpidas de humo contra un binario o un punto final en tiempo real.
Fuzzing de caja blanca Cรณdigo fuente completo, a menudo combinado con ejecuciรณn simbรณlica para resolver bifurcaciones de difรญcil acceso. Anรกlisis exhaustivo de un componente cuya fuente estรก disponible.
Fuzzing de caja gris No se realiza una revisiรณn del cรณdigo fuente, sino que se proporciona retroalimentaciรณn en tiempo de ejecuciรณn, como por ejemplo a quรฉ ramas del cรณdigo llegรณ una entrada. El valor predeterminado para motores modernos como AFL++ y libFuzzer.

Una segunda divisiรณn, mรกs antigua, separa fuzzing tonto desde Fuzzing inteligenteUn fuzzer bรกsico manipula los bits sin tener idea del formato de entrada, por lo que la mayor parte de sus datos son rechazados por el primer analizador sintรกctico que encuentra. Un fuzzer inteligente comprende las sumas de verificaciรณn, los campos de longitud y la estructura del mensaje, por lo que sus entradas superan la validaciรณn y llegan a la lรณgica subyacente. Fuzzing guiado por cobertura Es el refinamiento de la caja gris lo que hizo que el fuzzing se popularizara: el motor instrumenta el binario, conserva cualquier entrada que llegue a una nueva rama y muta los supervivientes, de modo que el corpus evoluciona constantemente hacia cรณdigo inexplorado en lugar de reiniciarse desde ruido aleatorio.

Cรณmo hacer pruebas difusas

Los pasos para realizar pruebas de fuzzing incluyen los pasos bรกsicos de prueba:

Paso 1) Identificar el sistema objetivo โ€” Elija el binario, la biblioteca, el servicio o el punto final del protocolo que se atacarรก y confirme que tiene permiso para probarlo.

Paso 2) Identificar las entradas โ€” enumera todos los puntos de entrada desde los que lee el objetivo: archivos, argumentos de lรญnea de comandos, variables de entorno, paquetes de red, campos de formulario y cargas รบtiles de API.

Paso 3) Generar datos difusos โ€” producir entradas mal formadas mutando muestras vรกlidas, generรกndolas a partir de un modelo del formato o combinando ambos mรฉtodos.

Paso 4) Ejecutar la prueba utilizando datos difusos โ€” Ejecutar el programa objetivo con los datos de entrada generados, idealmente en un bucle que reinicie el proceso automรกticamente despuรฉs de cada fallo.

Paso 5) Monitorear el comportamiento del sistema โ€” Presta atenciรณn a los fallos, bloqueos, errores de aserciรณn, uso excesivo de memoria e informes del analizador, en lugar de limitarte a comprobar la salida impresa.

Paso 6) Registrar defectos โ€” guarda la entrada exacta que desencadenรณ cada fallo, redรบcela al caso reproducible mรกs pequeรฑo y archรญvala con la pila. trace adjunto.

Ejemplos de fuzzers

Los fuzzers tambiรฉn se clasifican segรบn cรณmo construyen su entrada, y los tres enfoques que se describen a continuaciรณn son los que encontrarรก con mayor frecuencia.

  • Fuzzers basados โ€‹โ€‹en mutaciones Modificar muestras de datos existentes para crear nuevos datos de prueba. Este es un mรฉtodo muy simple y directo: comienza con muestras vรกlidas de un protocolo y va alterando cada byte o archivo.
  • Fuzzers basados โ€‹โ€‹en generaciรณn definen nuevos datos basรกndose en la entrada del modelo. Comienzan a generar la entrada desde cero basรกndose en la especificaciรณn.
  • Fuzzers basados โ€‹โ€‹en protocolos Dependen de un conocimiento detallado del formato del protocolo que se estรก probando, y esa comprensiรณn proviene de la especificaciรณn. Implica escribir una matriz de la especificaciรณn en la herramienta y luego usar una tรฉcnica de generaciรณn de pruebas basada en modelos para recorrer la especificaciรณn y agregar irregularidades en el contenido de los datos, la secuencia, etc. Esto tambiรฉn se conoce como prueba de sintaxis, prueba de gramรกtica o prueba de robustez. Un fuzzer puede generar casos de prueba a partir de uno existente, o puede usar entradas vรกlidas o invรกlidas.

Existen dos limitaciones de la fuzzing basada en protocolos:

  1. Las pruebas no pueden continuar hasta que la especificaciรณn estรฉ madura.
  2. Muchos protocolos รบtiles son una extensiรณn de los protocolos publicados. Si las pruebas fuzz se basan en especificaciones publicadas, Cobertura de prueba para nuevos protocolos serรก limitado.

La tรฉcnica de fuzzing mรกs sencilla consiste en enviar datos aleatorios al software, ya sea como paquetes de protocolo o como eventos. Esta tรฉcnica es muy eficaz para detectar errores en numerosas aplicaciones y servicios. Existen otras tรฉcnicas, muy fรกciles de implementar. Para implementarlas, basta con modificar las entradas existentes, simplemente intercambiando sus bits.

Tipos de errores detectados por Fuzz Testing

Dado que las pruebas de fuzzing evalรบan una ejecuciรณn en funciรณn del comportamiento del programa y no de un valor esperado, los defectos que detecta se agrupan en tres familias.

  • Fallos de aserciรณn y fugas de memoria: Esta metodologรญa se utiliza ampliamente en aplicaciones de gran tamaรฑo donde los errores afectan a la seguridad de la memoria, lo que constituye una vulnerabilidad grave. Buffer Aquรญ aparecen los desbordamientos, el uso de memoria liberada y las lecturas fuera de lรญmites.
  • Entrada no vรกlida: En las pruebas de fuzzing, los fuzzers se utilizan para generar entradas no vรกlidas que se utilizan para probar rutinas de manejo de errores, y esto es importante para el software que no controla su entrada. El fuzzing simple puede verse como una forma de automatizar prueba negativa.
  • Errores de correcciรณn: Las pruebas de fuzzing tambiรฉn pueden utilizarse para detectar ciertos tipos de errores de "correcciรณn", como una base de datos corrupta o resultados de bรบsqueda deficientes. El fuzzing diferencial, que consiste en introducir la misma entrada en dos implementaciones y comparar las respuestas, es la forma habitual de detectarlos.

Herramientas de prueba de fuzz

Las herramientas que se utilizan en la seguridad web se pueden utilizar ampliamente en las pruebas de fuzzing, como por ejemplo: Burp Suite y Peach Fuzzer. Varios de los nombres clรกsicos que aparecen a continuaciรณn estรกn archivados, por lo que su estado actual se indica junto a cada entrada.

  • Melocotรณn Fuzzer: Peach Fuzzer proporciona una cobertura de seguridad mรกs robusta que un escรกner. Otras herramientas de prueba solo pueden buscar amenazas conocidas, mientras que Peach Fuzzer permite a los usuarios encontrar amenazas conocidas y desconocidas. Peach Tech fue adquirida por GitLab, y Community Edition v3 ya no recibe mantenimiento; el sucesor con mantenimiento es el GitLab Protocol Fuzzer Ediciรณn Comunitaria.
  • Proxy de pico: una herramienta de nivel profesional que busca vulnerabilidades a nivel de aplicaciรณn en aplicaciones web. SPIKE Proxy cubre los aspectos bรกsicos, como: SQL Inyecciรณn y secuencias de comandos entre sitios, en un entorno completamente abierto. Python infraestructura, y estaba disponible para Linux y WindowsNo se le ha dado mantenimiento durante muchos aรฑos y se incluye aquรญ a modo de contexto histรณrico.
  • Escarabajo web: WebScarab estรก escrito en Java Por lo tanto, es compatible con mรบltiples plataformas. El framework WebScarab se comunica mediante los protocolos HTTP y HTTPS y funciona como un proxy interceptor: permite al operador revisar y modificar las solicitudes creadas por el navegador antes de que el servidor las reciba, asรญ como revisar y actualizar las respuestas generadas por el servidor antes de que el navegador las reciba. Cualquier vulnerabilidad que WebScarab detecte se aรฑade a su lista de problemas reportados. El repositorio se archivรณ en abril de 2024 y actualmente es de solo lectura.
  • Fusible OWASP WSFuzzer: WSFuzzer es un programa con licencia GPL escrito en Python que se dirigรญa a los servicios web y en su รบltima versiรณn basada en HTTP. Servicios SOAP eran el objetivo principal. Se lanzรณ como parte de WebScarab y se retirรณ con รฉl; OWASP ZAP y su complemento Fuzzer son el reemplazo recomendado.
  • Alternativas mantenidas: AFL++ y libFuzzer son los motores estรกndar de cobertura guiada para cรณdigo nativo, OSS-Fuzz Los ejecuta de forma continua y gratuita para proyectos de cรณdigo abierto, y boofuzz cubre el fuzzing de protocolos de red en Python. Una lista mรกs amplia se recoge en la guรญa de herramientas de prueba de seguridad.

Mejores prรกcticas de pruebas fuzz

Un fuzzer que apunta a un objetivo y se deja solo rara vez encuentra algo รบtil. Las prรกcticas que se describen a continuaciรณn distinguen una campaรฑa que genera defectos registrados de una que solo consume tiempo de CPU.

  • Comience con un buen corpus semilla. Recopila datos de entrada reales y vรกlidos que la aplicaciรณn ya acepta. Modificar un archivo autรฉntico permite acceder al cรณdigo de anรกlisis mucho mรกs rรกpido que modificar bytes aleatorios.
  • Escribe un arnรฉs pequeรฑo y rรกpido. El punto de entrada debe realizar una sola acciรณn por ejecuciรณn, evitar llamadas de red y escrituras en disco, y devolver un resultado rรกpidamente, ya que el rendimiento se mide en ejecuciones por segundo.
  • Enciende los desinfectantes. La corrupciรณn silenciosa de la memoria a menudo no provoca un fallo del sistema. AddressSanitizer y UndefinedBehaviorSanitizer la convierten en un fallo inmediato y diagnosticable.
  • Corre mucho y corre sin parar. Una ejecuciรณn de una o dos horas detecta errores superficiales; los problemas mรกs complejos suelen requerir muchas horas, por lo que las pruebas de fuzzing deben realizarse en un proceso de integraciรณn continua nocturno en lugar de una sesiรณn manual.
  • Minimiza y elimina los duplicados de cada fallo. Reduzca la entrada que falla a su forma mรกs pequeรฑa y agrupe los fallos por pila. trace, de lo contrario, un error se convierte en cientos de tickets.
  • Mantรฉn un corpus de regresiรณn. Agregue cada entrada que reproduce el problema a un conjunto permanente que se ejecuta en cada compilaciรณn, de modo que un defecto corregido no pueda volver a aparecer sin previo aviso.
  • Delimite el alcance del objetivo legalmente. Realizar pruebas de fuzzing en un servicio de terceros en funcionamiento sin permiso por escrito es indistinguible de un ataque.

Ventajas de las pruebas fuzz

Utilizada con expectativas realistas, la tรฉcnica de fuzzing aรฑade un valor que otras tรฉcnicas no logran igualar.

  • Las pruebas de fuzzing mejoran las pruebas de seguridad del software.
  • Los errores detectados en las pruebas de fuzzing a veces son graves y suelen ser los mismos que utilizan los atacantes, incluyendo fallos del sistema, fugas de memoria y excepciones no controladas.
  • Si algรบn error no es detectado por los evaluadores debido a limitaciones de tiempo y recursos, esos errores tambiรฉn se encuentran en las pruebas de fuzzing.
  • Los datos de entrada son generados por una mรกquina, por lo que la cobertura sigue creciendo durante la noche sin necesidad de esfuerzo manual adicional.

Desventajas de las pruebas Fuzz

Las mismas propiedades que hacen que el fuzzing sea barato tambiรฉn limitan lo que puede demostrar.

  • Las pruebas de fuzzing por sรญ solas no pueden proporcionar una imagen completa de una amenaza de seguridad general o de un conjunto de errores.
  • Las pruebas de fuzzing son menos efectivas para hacer frente a las amenazas de seguridad que no provocan fallos en los programas, como algunos virus, gusanos y troyanos.
  • Las pruebas de fuzzing solo pueden detectar fallos o amenazas relativamente simples y no razonan sobre la lรณgica empresarial.
  • Para funcionar eficazmente, requiere un tiempo de mรกquina considerable.
  • Establecer una condiciรณn de valor lรญmite con entradas aleatorias es muy problemรกtico, aunque los evaluadores ahora resuelven gran parte de esto con algoritmos deterministas basados โ€‹โ€‹en las entradas del usuario.

Pruebas de fuzzing frente a pruebas de penetraciรณn

Ambas actividades buscan fallos de seguridad, pero responden a preguntas diferentes y rara vez son intercambiables.

Criterios Prueba de fuzz Pruebas de penetraciรณn
Accionada por Un motor automatizado que genera una entrada mal formada Un probador experto razonando sobre el sistema
Busca Bloqueos, cuelgues y fallos de seguridad de memoria. Debilidades explotables, incluyendo fallos de lรณgica y configuraciรณn.
Profundidad Cobertura de entrada muy amplia, razonamiento superficial. Cobertura limitada, razonamiento profundo
Resultado Reproducciรณn de entradas y pila traces Un informe de resultados con rutas de explotaciรณn y calificaciones de riesgo.
Mejores momentos De forma continua, en la canalizaciรณn de compilaciรณn Periรณdicamente, contra un candidato a lanzamiento

En la prรกctica, ambos procesos se retroalimentan: las pruebas de fuzzing eliminan los fallos fรกciles de automatizar, de modo que las limitadas horas de un probador se dediquen a detectar los fallos que solo un ser humano podrรญa identificar.

Preguntas Frecuentes

Un corpus semilla es el conjunto inicial de entradas vรกlidas que el fuzzer modifica. Los archivos pequeรฑos, variados y reales funcionan mejor, porque cada uno ya pasa el analizador sintรกctico y permite que el motor dedique su presupuesto a cรณdigo mรกs profundo en lugar de a la primera comprobaciรณn de validez.

Un arnรฉs de fuzzing es una pequeรฑa funciรณn que pasa un bรบfer de bytes fuzzeados al cรณdigo que se estรก probando. Debe evitar el estado global, las escrituras en archivos y las llamadas de red, para que el motor pueda ejecutarlo miles de veces por segundo.

Una o dos horas bastan para detectar errores menores. Las campaรฑas serias duran muchas horas o incluso dรญas, porque la informaciรณn llega en oleadas. Una meseta en la curva de cobertura, y no una lectura del reloj, es la seรฑal clara de que una campaรฑa ha dejado de ser rentable.

AddressSanitizer detecta desbordamientos de bรบfer y uso de memoria liberada, UndefinedBehaviorSanitizer detecta el uso indebido de enteros y punteros, y MemorySanitizer detecta lecturas de memoria no inicializada. Sin estas herramientas, muchas corrupciones pasan desapercibidas y el fuzzer no informa de ningรบn fallo.

Reprodรบzcalo, minimice la entrada al caso de fallo mรกs pequeรฑo, agrรบpelo con fallos que compartan la misma pila. trace, luego presente una solicitud a travรฉs del procedimiento habitual proceso de gestiรณn de defectos y agregar la entrada a un corpus de regresiรณn.

Comparten la aleatoriedad, pero no la intenciรณn. Pruebas con monos El fuzzing lanza acciones de usuario arbitrarias a una interfaz en ejecuciรณn, mientras que el fuzzing se dirige a un analizador de entrada especรญfico y mide la cobertura del cรณdigo, de modo que puede orientarse hacia el cรณdigo al que las entradas anteriores nunca llegaron.

Los modelos de lenguaje se utilizan para diseรฑar sistemas de autenticaciรณn para API sin fuzzing, sintetizar entradas iniciales para formatos poco comunes y agrupar y resumir informes de fallos. El motor sigue proporcionando la informaciรณn de cobertura; el modelo elimina principalmente el trabajo de configuraciรณn manual.

Copiloto de GitHub Puede diseรฑar un punto de entrada de libFuzzer, un archivo de compilaciรณn y un generador de semillas a partir de una firma de API existente. RevExamine el resultado con atenciรณn, ya que un arnรฉs que ignora los errores silenciosamente no reportarรก fallos.

Resumir este post con: