Funciones inseguras, ¿todavía?

Agua El mundo de la seguridad informática es inabarcable. Por su extensión, que se amplía continuamente, pero también por su duración: todavía podemos encontrar programas vulnerables con fallos que se conocen desde hace quinquenios. Luego, otras veces olvidamos que aunque nuestro lenguaje favorito no sufra esos problemas directamente, puede que los tenga por la vía de los lenguajes en los que se ha desarrollado la infraestructura subyacente (el propio compilador/intérprete, las bibliotecas, el sistema…).

Por eso nos viene bien leer (y recordarlos) en artículos como Funciones inseguras de un futuro pasado. Habla de las funciones peligrosas a vista de pájaro y sugiere la utilización de las herramientas actuales para detectar y evitar esos fallos.

Pero, seguramente, seguirán apareciendo.

Divulgación coordinada de fallos de seguridad

Mosaico (piezas que encajan) Ya pasó el tiempo en que alguien hacía un gran descubrimiento de seguridad y lo publicaba en algún sitio para ganar fama y notoriedad: aunque pasa de vez en cuando, lo habitual es comunicarlo al interesado para que lo resuelva y luego llevarse el crédito de alguna forma (fama, pero también cobros de los programas de detección de fallos que casi todas las empresas tienen), o ¡ay! tratar de obtener algún tipo de beneficio económico en el mercado negro de vulnerabilidades.

Con eso en mente, vale la pena echarle un ojo a Your TL;DR Summary of The CERT Guide to Coordinated Vulnerability Disclosure donde se comenta sobre la publicación del CERT [PDF] The CERT Guide to Coordinated Vulnerability Disclosure.

Son interesantes los principios: reducir el daño, asumir la benevolencia (del informante), evitar sorpresas, incentivar el comportamiento deseado, tener en cuenta las consideraciones éticas, mejorar el proceso y concentrarse en mejorar las cosas y no en alcanzar la ‘última verdad verdadera’.

Reduce Harm - (Balance) the ability for system defenders to take action while avoiding an increase in attacker advantage.

Presume Benevolence - Assume that any individual who has taken the time and effort to reach out to a vendor or a coordinator to report an issue is likely benevolent and sincerely wishes to reduce the risk posed by the vulnerability.

Avoid Surprise - Clearly communicating expectations across all parties involved in a CVD process.

Incentivize Desired Behavior - Incentives can take many forms…recognition, gifts, money, employment.

Ethical Considerations - The Usenix’ System Administrators’ Code of Ethics includes an ethical responsibility “to make decisions consistent with the safety, privacy, and well-being of my community and the public, and to disclose promptly factors that might pose unexamined risks or dangers.”

Process Improvement - Capture ideas that worked well and note failures. A successful CVD program feeds vulnerability information back into the vendor’s Software Development Lifecycle, (and) helps encourage the search for and reporting of vulnerabilities while minimizing harm to users.

CVD as a Wicked Problem - The goal of a solution is not to find an ultimate truth about the world, rather it is to improve conditions for those who inhabit it.

Interesante.

Coches informáticos

Coche de gama alta Creo que hay poca duda sobre lo que compramos hoy en día. Un coche es un ordenador con ruedas y motor. Un frigorífico es un ordenador con una caja cerrada fría y una televisión es un ordenador con una pantalla un poco especial, más grande que las que tienen normalmente los ordenadores. Algunos nos quejaríamos de que sean ordenadores poco potentes, y poco accesibles, pero es lo que hay.

En This Car Runs on Code nos lo recordaban ya desde el título y del párrafo introductorio, donde dice eso de que hacen falta docenas de microprocesadores ejecutando millones de líneas de código para sacar un coche de gama alta a la carretera:

It takes dozens of microprocessors running 100 million lines of code to get a premium car out of the driveway, and this software is only going to get more complex

Además del mensaje tan pontente que nos transmite eso, este artículo me gustó por otras cifras, por ejemplo las relacionadas con diversos ‘aparatos’.

El F-22, F-35, un Boeing 787…

The avionics system in the F-22 Raptor, the current U.S. Air Force frontline jet fighter, consists of about 1.7 million lines of software code. The F-35 Joint Strike Fighter, scheduled to become operational in 2010, will require about 5.7 million lines of code to operate its onboard systems. And Boeing’s new 787 Dreamliner, scheduled to be delivered to customers in 2010, requires about 6.5 million lines of software code to operate its avionics and onboard support systems.

Pero también, algo tan ‘simple’ como el sistema de radio y navegación de un Mercedes clase S:

Alfred Katzenbach, the director of information technology management at Daimler, has reportedly said that the radio and navigation system in the current S-class Mercedes-Benz requires over 20 million lines of code alone …

No sólo eso, claro, sino que se trata de sistemas que deben seguir funcionando en condiciones de poco confort:

… have to be able to operate for years in temperatures ranging from the dead of a freezing Minnesota winter to the blazing heat of an Arizona summer sun.

Respecto, al coste, casi una tercera parte viene de estos sistemas en los coches de gama alta:

For today’s premium cars, ”the cost of software and electronics can reach 35 to 40 percent of the cost of a car,” states Broy, with software development contributing about 13 to 15 percent of that cost.

Y luego, vienen los problemas: fallos de software:

IBM claims that approximately 50 percent of car warranty costs are now related to electronics and their embedded software, costing automakers in the United States around $350 and European automakers 250 per vehicle in 2005.

Dificultad para reparar:

The increased use of software has not only affected car warranty costs but has also made cars harder to repair—so much so that insurance companies increasingly find it cheaper to declare cars damaged in accidents total losses than it is to fix them.

Interesante. Y numerológico.

Cadenas de formato en Windows

Ventanas En el apartado de problemas de seguridad no tan conocidos pero que tienen su interés están los fallos relacionados con las cadenas de formato. En C, cuando en una instrucción de escritura printf y similares no se pone cadena de formato, puede ocurrir que la entrada proporcionada por el usuario termine interpretándose como tal. Si a eso añadimos la característica (no tan conocida) de que algunos formatos no son sólo de salida sino que permiten leer y escribir, y además también podemos suministrarle las direcciones para hacerlo, tenemos abierta la puerta al desastre.

En Exploiting Format Strings in Windows nos hablaban justamente de este tema, en Windows.

Para las personas a las que les gusta tocar y jugar con los fallos.

Vulnerabilidades en los lenguajes que nos permiten desarrollar programas

Herramientas de construcción Tenemos que tenerlo claro: construir un sistema informático seguro es difícil. Los fallos pueden venir de tantos sitios, incluso incontrolables por nosotros que siempre puede pasar algo (malo). En este caso traemos Secure Apps Exposed to Hacking via Flaws in Underlying Programming Languages donde nos hablan de como aplicaron las técnicas de Fuzzing para identificar vulnerabilidades en intérpretes de diferentes lenguajes de programación.

Recordemos que el fuzzing consiste en proporcionar entradas inesperadas (simpelmente basura, muchas veces) a una interfaz para ver qué sucede. Muchas veces, cosas malas, que señalan diversos problemas.

Fuzzing is an operation that involves providing invalid, unexpected, or random data as input to a software application. Fuzzing has been used for years in the software testing field but has recently become very popular with security researchers, especially with Google’s security team and the Linux community.

En este caso se evaluaron intérpretes de JavaScript, Perl, PHP, Ruby y Python.

The author of this research is IOActive Senior Security Consultant Fernando Arnaboldi. The expert says he used an automated software testing technique named fuzzing to identify vulnerabilities in the interpreters of five of today’s most popular programming languages: JavaScript, Perl, PHP, Python, and Ruby.

Un resumen de los descubrimientos:

  • Python contiene métodos no documentados y variables de entorno que pueden utilizarse para ejecutar instrucciones del sistema operativo.
  • Perl incluye una función typemaps que permite la ejecución de código similar a eval()
  • NodeJS muestra mensajes de error que divulgan parcialmente el contenido de ficheros.
  • JRuby carga y ejecuta código remoto en funciones que no deberían permitirlo.
  • Los nombres de constantes de PHP permitirían ejecutar instrucciones de manera remota.

➣ Python contains undocumented methods and local environment variables that can be used for OS command execution.

➣ Perl contains a typemaps function that can execute code like eval().

➣ NodeJS outputs error messages that can disclose partial file contents.

➣ JRuby loads and executes remote code on a function not designed for remote code execution.

➣ PHP constant’s names can be used to perform remote command execution.

El artículo es de hace un par de años así que estos fallos se habrán solucionado. Pero da miedo.

Fallos en el kernel de Linux

Bicho Con lo que sabemos hoy en día parece que es prácticamente imposible entregar un producto informático sin fallos (aunque hay quien dice que puede hacerlo bastante bien), System complexity, safety, security drive continued adoption of Ada, SPARK in aerospace and defense software engineering).

También nos gusta bastante la cantidad de cosas que se pueden aprender de los productos de código abierto, donde se puede mirar, medir y aprender (Bitergia, por ejemplo, se dedica a eso).

Podíamos leer en Static analysis on the Linux kernel los resultados de diferentes mediciones realizadas sobre el kernel de Linux, principalmente los análisis que realiza la empresa Coverity sobre diversos proyectos de software libre. El resumen sería este:

As one can see, there are a lot of defects getting fixed by the Linux developers and the overall trend of outstanding issues is downwards, which is good to see. The defect rate in linux-next is currently 0.46 issues per 1000 lines (out of over 13 million lines that are being scanned). A typical defect rate for a project this size is 0.5 issues per 1000 lines. Some of these issues are false positives or very minor / insignificant issues that will not cause any run time issues at all, so don’t be too alarmed by the statistics

Esto es, en el Kernel de Linux tiene una tasa de defectos de 0.46 por cada mil líneas, teniendo en cuenta que es una prueba automatizada que detectará como fallos cosas que no lo son, y dejará de detectar otros.

Algunos aspectos prácticos de la autentificación de dos factores

Puerta Llevamos una temporada escuchando que la autentificación con dos factores es la solución para los problemas de las malas contraseñas que eligen los usuarios y otros problemas de la autentificación mediante contraseña. La autentificación de dos factores se vió puesta en entredicho este verano por la inseguridad de los SMS Reddit hack highlights vulnerability of two-factor authentication. No obstante, podemos ver en Inside Two-Factor Authentication Apps proporcionan algunas pistas interesantes y una introducción al tema que podemos leer, con ejemplos de código en Python.

So I’m going to step quickly through how 2FA apps work, and then show you how you can implement it yourself if you want in a few lines of Python.

Para hacer una autentificación de dos factores, en la práctica, muchcas aplicaciones utilizan para generar el segundo factor el algoritmo de clave de un solo uso basado en tiempo:

In practice, because of cost and convenience, most 2FA implementations use an app that authenticates using the time-based one-time password (TOTP) algorithm. That is, it’s just another password.

Se basan en una contraseña secreta, un secreto compartido (el momento de la petición) y una función de hash:

The beauty of these algorithms is that the one-time secret password is hashed with some other number that’s common knowledge to me and the server — sometimes it’s a simple counter. This generates a different “password” for every value of the counter.

Para no tener problemas con las diferencias de tiempo entre el cliente y el servidor hace falta un pequeño ajuste, que consiste en habilitar tramos de alrededor de 30 segundos y, además, dar por bueno el anterior y el posterior:

In most TOTP implementations, the counter is the number of 30 second intervals that have elapsed since Jan 1, 1970 — the Unix epoch. This gives you a different, strong, password every 30 seconds. Practically, servers will accept either the previous, current, or next values to allow for clocks to go a little out of sync, but after a minute or so, that old hashed value is useless to an attacker. That’s pretty cool

Interesante.

Cuatro ideas para asegurar la autentificación

Puerta El sistema de autentificación de los usuarios sigue siendo la única puerta de entrada a las caraterísticas de nuestro sistema que podamos ofrecerles. Por este motivo, es una fuente segura de ataques, con diversas formas de intentar atacarnos para ver qué se puede conseguir.

En 4 Ways to Secure Your Authentication System in Rails hablan del tema para aplicaciones desarrolladas en Ruby on Rails, aunque las ideas se pueden aplicar en otros contextos.

Los consejos:

  • Restringir las peticiones. Esto es, tratar de evitar los ataques de fuerza bruta, donde el ‘malo’ simplemente va probando diferentes identificadores y credenciales.

  • Poner las cabeceras de seguridad correctamente. Estar al día en las novedades y modificar nuestras aplicaciones no es un asunto trivial, pero tampoco es normal no aprovechar de las ventajas de unas cabeceras adecuadas (Recordatorio: El uso de las cabeceras de los sitios web populares para aprender de seguridad).

  • Leer bibliotecas de autentificación. Leer el código de otros proyectos puede ayudarnos a hacer mejor las cosas nosotros. También el registro de cambios changelog Da como ejemplo algunas características de algunas bibliotecas de las que se pueden aprender cosas interesanets (almacenamiento de hash de contraseñas separados y otros).

  • Asegurar el resto de la aplicación. Claro. Da igual tener el mejor sistema de autentificación si pueden entrar por otro sitio.

Seguir la corriente resolviendo problemas y la seguridad

Seguir la corriente Ya hace años que es una queja frecuente en el mundillo de la seguridad: cuando te enseñan a programar, no sólo no te enseñan seguridad sino que los ejemplos que te muestran son en muchos casos una muestra de lo que no debe hacerse si te preocupa la seguridad.

Ya pasaba en los libros pero ahora hay un estudio sobre el mismo tema con los ejemplos en foros bien reconocidos de programadores. Nos lo contaban en Try Catch Stack Overflow y hablan de un estudio ([PDF] Secure Coding Practices in Java: Challenges and Vulnerabilities) donde han analizado la calidad del código que podemos encontrar en el conocido sitio StackOverflow y otros similares donde se reproduce el mismo patrón. Algunas respuestas populares y bien calificadas contienen vulnerabilidades desde el punto de vista de la seguridad.

Basado en el estudio sobre las preguntas y respuestas dadas en torno al lenguaje y plataforma Java, los investigadores han encontrado multitud de errores en respuestas populares que contienen vulnerabilidades de seguridad. El problema, señalan, no se encuentra en las librerías usadas –que no deja de ser reutilización legítima de código-, sino en que estas no se usan de forma segura, dando lugar a la exposición de riesgo por falta de pericia en su uso.

Naturalmente, no es una crítica al sitio, que es un recurso maravilloso cuando uno no sabe muy bien cómo avanzar. Pero debemos mantener el espíritu crítico y no seguir los consejos ciegamente, porque tendremos problemas.