GnuTLS corrige el error de mala gestión de la memoria: ¡actualice ahora!

Nodo de origen: 1603833

La librería criptográfica más conocida en el mundo del código abierto es casi seguro OpenSSL.

En primer lugar, es uno de los más utilizados, hasta el punto de que la mayoría de los desarrolladores en la mayoría de las plataformas han oído hablar de él aunque no lo hayan utilizado directamente.

En segundo lugar, es probablemente el más publicitado, lamentablemente debido a un error bastante desagradable conocido como heartbleed que fue descubierto hace más de ocho años.

A pesar de ser parcheado rápidamente (y a pesar de que existen soluciones confiables para los desarrolladores que no pudieron o no quisieron actualizar rápidamente sus versiones vulnerables de OpenSSL), Heartbleed sigue siendo una especie de error de "escaparate", sobre todo porque fue uno de los primeros errores en ser convertido en un agresivo vehículo de relaciones públicas por sus descubridores.

Con un nombre impresionante, un logotipo propio y un sitio web dedicado, Heartbleed se convirtió rápidamente en una ciberseguridad global. superhistoria, y, para bien o para mal, quedó inextricablemente vinculado con las menciones del nombre OpenSSL, como si el peligro del error persistiera incluso después de haber sido eliminado del código.

La vida más allá de OpenSSL

Pero hay varias otras bibliotecas criptográficas de código abierto que se usan ampliamente, además de OpenSSL o en lugar de ella, en particular, la de Mozilla. NSS (corto para Servicios de seguridad de red) y el proyecto GNU GnuTLS biblioteca.

Da la casualidad de que GnuTLS acaba de corregir un error conocido como CVE-2022-2509, reportado en el proyecto asesoramiento de seguridad GNUTLS-SA-2022-07-07.

Este parche corrige un error de mala gestión de la memoria conocido como doblemente libre.

Doble-libre explicado

En pocas palabras, se crea una vulnerabilidad de doble libertad cuando un programador le pide al sistema operativo que asigne un bloque de memoria para usar temporalmente...

…y lo devuelve para que pueda ser borrado de la lista de bloques prestados para ser liberados para su uso por otras partes del programa…

… y luego, accidentalmente, le pide al sistema que libere el mismo bloque de memoria nuevamente.

Idealmente, el software de asignación de memoria detectará que el bloque ya no pertenece a la parte del programa que lo está "devolviendo", descubrirá que el bloque ofensivo ya ha sido reciclado y no lo desasignará por segunda vez, eludiendo así los riesgos de “liberarlo” nuevamente.

Lidiar con cuidado con un doble-libre que se detecta de manera proactiva es un tema complicado. La función C que devuelve la memoria se prototipa como void free(void *ptr); para que pase la dirección de un bloque que desea liberar, pero no obtenga un código de retorno. (Función AC con void el valor de retorno es lo que otros lenguajes de programación llaman un procedure: hace algo por usted, pero no tiene forma de informar un resultado). Por lo tanto, incluso el código C cuidadosamente escrito no tiene una forma estándar de detectar que algo salió mal en free()y, por lo tanto, no hay forma de manejar el error al intentar cerrar correctamente. La terminación unilateral del programa ofensivo es la única solución segura para el sistema.

Pero si la asignación de memoria no se da cuenta (tal vez porque ese mismo bloque se ha entregado desde entonces a otra parte del mismo programa, por lo que está de vuelta en la lista de "prestados" exactamente en la misma forma que antes) , entonces es probable que sucedan cosas malas.

En particular, el administrador de memoria podría "confiscar" inadvertida e inesperadamente el bloque de doble liberación del código que ahora lo usa legítimamente y reasignarlo a otra parte del programa, tal vez incluso a un código malicioso que un atacante ha programado cuidadosamente para aprovechar. de la mala gestión.

Entonces, podría terminar con dos partes del mismo programa manipulando la misma porción de memoria.

Una parte del programa asume que puede confiar implícitamente en el contenido de la memoria, porque se considera el "propietario" legítimo del bloque.

Al mismo tiempo, otra parte del programa sabe que puede interferir con los datos (o puede ser engañado para alterarlos) para hacer tropezar a la primera parte deliberadamente.

Hacer lo incorrecto hace lo correcto

Irónicamente, el error CVE-2022-2509 existe en el código de verificación del certificado en GnuTLS.

(La ironía, en caso de que se lo pregunte, es que el software que es inseguro en general porque no se molesta en buscar conexiones TLS confiables es inmune a este error de seguridad específico).

Por ejemplo, cuando visita un sitio web (u otro tipo de servidor) que está protegido con TLS, el otro extremo generalmente le enviará un certificado web que afirma que el servidor realmente es propiedad de la organización que espera y está operado por ella.

Por supuesto, dado que cualquiera puede crear un certificado con el nombre que desee, un certificado sin procesar por sí solo no dice mucho, por lo que el propietario del certificado generalmente lo firma digitalmente por una empresa en la que su navegador ya confía.

En la práctica, los certificados suelen estar firmados por un certificado que, a su vez, está firmado por un certificado en el que confía su navegador, pero el resultado final es lo que se denomina un cadena de confianza que se puede rastrear de forma segura a un certificado que ya está instalado en una lista de los llamados Autoridades de confianza, también conocido como Raíces, que es administrado por su navegador o su sistema operativo.

Para simplificar y acelerar el proceso de validación de la cadena de certificados, muchos servidores no solo envían su propio certificado y dejan que el navegador "persiga la cadena" hasta una raíz de confianza.

El servidor generalmente incluye la cadena de confianza en la que se basa, que solo necesita construir una vez, de modo que su navegador, o cualquier software que esté verificando el certificado, pueda simplemente verificar que la cadena sea digitalmente válida y luego verificar que el último certificado en la cadena coincide con uno que ya es de confianza.

En ese caso, GnuTLS validará de forma correcta y segura el certificado proporcionado, antes de liberar el bloque de memoria que acaba de usarse para almacenarlo.

Pero si el otro extremo no proporciona una cadena de certificados pregenerada, lo que deja a GnuTLS para crear y verificar la cadena por sí solo, entonces el código GnuTLS libera accidentalmente la memoria utilizada para almacenar el certificado proporcionado antes de que comience la cadena. proceso de control…

…y luego lo libera nuevamente después de completar la verificación.

Esto provoca un percance de doble liberación, lo que podría provocar daños en la memoria, seguido de un bloqueo del programa.

Supervisar un bloqueo para implantar malware

Por lo general, o al menos con frecuencia, los bloqueos provocan un comportamiento tan caprichoso que el sistema operativo detecta que el programa infractor ha perdido el control del flujo de ejecución del programa; por ejemplo, si el programa salta a una dirección de memoria aleatoria e intenta ejecutar código desde un bloque de memoria que no se ha asignado en absoluto.

En este caso, el bloqueo provocaría un error del sistema, y ​​aunque se podría abusar de este tipo de error para lo que se denomina un Denegación de servicio (DoS), donde el objetivo completo es simplemente interrumpir el programa que está siendo atacado, no conduce a Ejecución remota de código (RCE), donde en su lugar se activa un código de software no deseado y que no es de confianza.

Pero cada vez que hay un bloqueo del programa que los atacantes pueden provocar a voluntad, en función de los datos no confiables que ellos mismos proporcionaron, siempre existe el riesgo de que el bloqueo pueda ser controlado de tal manera que desvíe el programa bloqueado para que salte al código ejecutable provisto. por los atacantes.

Como puede imaginar, los atacantes a menudo pueden explotar tales vulnerabilidades para implantar malware, ya sea de manera temporal o permanente, dado que pueden inyectar código no confiable en su computadora sin producir ninguna advertencia emergente que solicite permiso primero.

¿Qué hacer?

Actualización a la última versión de GnuTLS, que es 3.7.7 en el momento de escribir.

(Este error aparentemente se introdujo en GnuTLS 3.6.0 y existe en todas las versiones desde entonces, hasta la 3.7.6 inclusive).

Tenga en cuenta que muchas aplicaciones populares y kits de herramientas de programación incluyen o pueden estar diseñados para hacer uso de GnuTLS, aunque es posible que no lo sepa, incluidos, entre otros: FFmpeg, GnuPG, Mplayer, QEMU, Rdesktop, Samba, Wget, Wireshark y Zlib.

Muchos paquetes de Linux o *BSD que usan GnuTLS dependerán de una versión central administrada por su propia distribución, así que asegúrese de actualizar tan pronto como su distribución tenga esta versión disponible.

¡Feliz parcheo!


Sello de tiempo:

Mas de Seguridad desnuda