Para considerar que una aplicación es segura se tiene que construir con una metodología que involucre, desde su concepción,  la seguridad o bien incorporarle herramientas que busquen exhaustivamente defectos para su inmediata corrección.

La seguridad y la funcionalidad han sido siempre dos aspectos encontrados en materia de TI, si se aumenta uno, el precio se paga con la disminución del otro, y es que a través de los años el entrenamiento para el personal encargado de desarrollo de aplicaciones tradicionalmente no se ocupa de incluir temas de seguridad.

Desarrollo seguro de aplicaciones

Ante la cada vez más común aparición de ataques de día cero, se tiene mayor probabilidad de que una vulnerabilidad en el código de una aplicación sea explotada durante un tiempo considerable antes de que se desarrolle el ajuste (parche) para el código; como es de suponerse, cualquier retraso se traduce en un impacto económico para la organización.

Así pues, una alternativa de primera mano es hacer un drástico cambio en la cultura de los desarrolladores de código para que desde la concepción de un proyecto y a lo largo de las diferentes etapas que comprende el desarrollo de software se considere la seguridad. Los siguientes son algunos de los aspectos que comprende esta visión:

  • Manejar controles precisos que restrinjan el tipo de valores que se dan a las variables de entrada a una aplicación (inputs).
  • Incorporar mecanismos robustos de autenticación (contraseñas, tokens, biometría o bien la combinación de varios de ellos).
  • Realizar una definición y gestión adecuadas de los perfiles para proteger quién tiene acceso a un recurso y lo que puede hacer con él (autorización).
  • Definir  mecanismos para la salida de la aplicación que controlen lo que se pretende obtener después de la ejecución de un proceso (entregables de la aplicación y mensajes de error).
  • Incluir  mecanismos adecuados para detectar proactivamente cualquier anomalía (bitácoras de actividades).

 

El uso de fuzzers para garantizar la calidad del código

No existe, como habría de suponerse por la diversidad de aplicaciones y lenguajes de programación utilizados en TI, una fórmula única para contrarrestar las anomalías que se puedan dar en el código de una aplicación dada, sin embargo, existen herramientas que colaboran en entornos de prueba con el fin de aumentar el nivel de confiabilidad de las aplicaciones que se liberan para producción.

Entre estos mecanismos existen los fuzzers, herramientas que permiten hacer un primer nivel de pruebas al código introduciendo datos aleatorios e inválidos a un programa, de manera que si éste falla (cerrando la aplicación o provocando errores en ciertos módulos del programa) se agiliza la labor de localizar y corregir tempranamente defectos en el código.

Este enfoque de calidad de código nos permite probar si éste es robusto o si soporta fallas de sintaxis o pruebas negativas (es decir, entradas inaceptables como el uso de letras cuando se esperan solamente dígitos del 0 al 9 para el campo de “Edad” de una persona en una aplicación).

Para un fuzzer los blancos más comunes son los formatos de archivos, los protocolos de red, las variables de ambiente, o ciertas secuencias de teclas e inclusive movimientos del ratón. Para fines de hallazgos, que el fuzzer arroje resultados sobre una parte privilegiada de un sistema tiene más impacto que lo que se pueda encontrar entre interfaces hacia los usuarios de las mismas.

Cabe aclarar que las pruebas con fuzzers no pretenden sustituir los métodos formales exhaustivos, lo que entregarán es un primer panorama de cómo está la aplicación, y lo mejor que podríamos esperar es que nos den una idea de si la aplicación puede manejar excepciones (aseguramiento), mas no una certeza absoluta de que el código se comporte correctamente ante cualquier evento (localización de errores).

Clasificación de los fuzzers

De acuerdo a lo establecido anteriormente, se puede constituir una clasificación de los fuzzers con base en las afectaciones que realiza en los siguientes tipos:

  1. En el sistema de Archivos – Estas herramientas se encargan de crear archivos en el disco donde radica la aplicación, p. ej. FileH/FileP, FileFuzz
  2. Dentro del flujo de tráfico de Red – Los de esta clasificación insertan paquetes generados aleatoriamente en el flujo de la red, p.ej. TAOF, Sully, GPF, EFS
  3. Generales – Éstos usualmente son interfaces de entrada/salida que se adicionan a la aplicación que se tiene bajo prueba, p.ej. Peach, SPIKE, Fuzzled, Fuzzware
  4. Personalizados – Dentro de esta clasificación se ubican aquellas herramientas que son desarrolladas ex profeso para poner a prueba una aplicación, p.ej Fuzzers para LDAP, Axman, DOM-Hanoi, Hamachi, Mangleme

Existen diversas opciones en el mercado de fuzzers comerciales y de código abierto, por ejemplo “Mu Security” (http://www.mudynamics.com/products/Mu-Test-Suite/security-testing.html) que está pensado para aplicación en entornos de Redes, o “beSTORM” (http://www.beyondsecurity.com/black-box-testing.html) y “Codenomicon” (http://www.codenomicon.com/products/buzz-on-fuzzing.shtml) que están considerados para aplicación general.

Para crear fuzzers personalizados hay que tener en cuenta la necesidad de invertir recursos de tiempo y monetarios en su desarrollo, pruebas, entrenamiento de los aplicadores y en el mantenimiento de estas herramientas.

Proceso de aplicación de un fuzzer

Los procesos de pruebas de aplicaciones con fuzzers se apegan por lo general a las siguientes etapas:

  • Investigación – Donde se determina a qué porción de código se aplicará el «fuzzing» y se seleccionan las características de la herramienta que se deben explotar y los alcances de la misma.
  • Modelado – En esta etapa se escogen los atributos que se evaluarán en los datos, las relaciones entre ellos dentro de la ejecución del código y los estados del sistema durante la evaluación; esta etapa suele ser de las más consumidoras de tiempo.
  • Validación – Se verifica que lo definido en la etapa anterior encaja con la realidad; esto le dará sentido a los resultados que finalmente se generen.
  • Monitoreo – Esta etapa se encarga de detectar fallas, colectar información y puede implicar ajustes finos así como una configuración más detallada para obtener información realista y de valor para la organización. En el monitoreo se hace la labor de depuración de errores.
  • Corrida – Trabaja estrechamente con la etapa anterior y es aquí donde se define qué pasa tras la ocurrencia de una falla, ¿continúa el proceso aplicativo?, ¿termina?, ¿se puede ejecutar algo en paralelo?, ¿se invoca otro proceso?, ¿cuántas iteraciones?, etcétera.
  • Resultados – Es donde finalmente se obtienen los resultados de la prueba, donde se eliminan las duplicidades, se descartan los eventos que no son de interés y se realiza un análisis con profundidad de las fallas para dictaminar la calidad del código evaluado.

 

Conclusiones

Un argumento que suele esgrimirse es  ¿para qué necesitaría un fuzzer si hoy existen scanners de vulnerabilidades?, la respuesta es simple: los scanners se basan en la detección de ataques conocidos, de manera que no se puede encontrar una vulnerabilidad específica si ésta aún no es conocida. Cuando la vulnerabilidad se detecta, por lo general ya hay alguien en algún lugar explotándola.

De aquí se desprende la necesidad de contar con herramientas proactivas, como los fuzzers a los que hemos dedicado en esta ocasión un espacio de discusión en Magazcitum.  Las bases de datos de vulnerabilidades arrojan que 80% de las fallas en las aplicaciones se debe a errores de programación y que en este mismo porcentaje se presentarán fallas vía la aplicación de una herramienta de fuzzing. Si logramos vencer los actuales paradigmas del desarrollo de software lograremos tener cada vez código más robusto, aplicaciones más confiables y mejores niveles de productividad en un entorno cada vez más competido.

[email protected]

Para saber más:

  • Fuzzing for Software Security Testing and Quality Assurance.
    • Ari Takanen,  Jared DeMott, Charlie Miller.
    • Artech House Publishers, 1st edition (June 30, 2008).
  • Open Source Fuzzing Tools.
    • Noam Rathaus, Gadi Evron.
    • Syngress (December 28, 2007).