Se ha identificado una vulnerabilidad crítica (CVE-2021-43527) en el conjunto de bibliotecas criptográficas NSS (Network Security Services) desarrolladas por Mozilla, que puede permitir que un atacante ejecute código al procesar firmas digitales DSA o RSA-PSS definidas utilizando el método de codificación DER (Distinguished Encoding Rules). El problema, apodado BigSig, ha sido resuelto en las versiones NSS 3.73 y NSS ESR 3.68.1. Las actualizaciones de paquetes están disponibles para distribuciones como Debian, RHEL, Ubuntu, SUSE, Arch Linux y Gentoo, FreeBSD. Las actualizaciones para Fedora aún no están disponibles.
El problema se manifiesta en aplicaciones que utilizan NSS para procesar firmas digitales CMS, S/MIME, PKCS #7 y PKCS #12, o al verificar certificados en implementaciones TLS, X.509, OCSP y CRL. La vulnerabilidad puede surgir en varias aplicaciones cliente y servidor compatibles con TLS, DTLS y S/MIME, así como en clientes de correo y visores de PDF que usan la llamada NSS CERT_VerifyCertificate() para validar firmas digitales.
Entre los ejemplos de aplicaciones vulnerables se mencionan LibreOffice, Evolution y Evince. Potencialmente, el problema también puede afectar a proyectos como Pidgin, Apache OpenOffice, Suricata, Curl, Chrony, Red Hat Directory Server, Red Hat Certificate System, mod_nss para el servidor http Apache, Oracle Communications Messaging Server y Oracle Directory Server Enterprise Edition. Sin embargo, la vulnerabilidad no se presenta en Firefox, Thunderbird y Tor Browser, que utilizan una biblioteca separada mozilla::pkix para la verificación, que también forma parte de NSS. Los navegadores basados en Chromium tampoco están afectados (a menos que se hayan compilado específicamente con NSS), los cuales usaron NSS hasta 2015, pero luego se trasladaron a BoringSSL.
La vulnerabilidad es causada por un error en el código de verificación de certificados en la función vfy_CreateContext del archivo secvfy.c. El error se manifiesta tanto al leer el certificado del cliente desde el servidor como al procesar el servidor certificados de clientes. Durante el proceso de verificación de una firma digital codificada mediante DER, NSS decodifica la firma en un búfer de tamaño fijo y pasa este búfer al módulo PKCS #11. Durante el procesamiento posterior, para las firmas DSA y RSA-PSS, no se verifica correctamente el tamaño, lo que lleva a un desbordamiento del búfer asignado para la estructura VFYContextStr, si el tamaño de la firma digital supera los 16384 bits (se asignan 2048 bytes para el búfer, pero no se comprueba que la firma pueda ser más grande).
El código con la vulnerabilidad ha existido desde 2003, pero no representaba una amenaza hasta la reestructuración realizada en 2012. En 2017, al implementar el soporte para RSA-PSS, se cometió el mismo error. Para llevar a cabo un ataque, no se requiere la generación intensiva de ciertas claves para obtener los datos necesarios, ya que el desbordamiento ocurre en la etapa anterior a la verificación de la firma digital. La parte de datos que excede los límites se escribe en un área de memoria que contiene punteros a funciones, lo que facilita la creación de exploits funcionales.
La vulnerabilidad fue detectada por investigadores de Google Project Zero durante experimentos con nuevos métodos de pruebas de fuzzing, y es una buena demostración de cómo pueden permanecer vulnerabilidades triviales sin ser detectadas durante un largo período en un proyecto bien probado y conocido:
- El código NSS está acompañado de un equipo experimentado responsable de la seguridad, que aplica métodos modernos de pruebas y análisis de errores. Existen varios programas que ofrecen recompensas significativas por la detección de vulnerabilidades en NSS.
- NSS fue uno de los primeros proyectos en unirse a la iniciativa de Google oss-fuzz y también fue verificado en el sistema de pruebas de fuzzing en desarrollo de Mozilla basado en libFuzzer.
- El código de la biblioteca ha sido revisado múltiples veces en varios analizadores estáticos, incluyendo el servicio Coverity que lo ha rastreado desde 2008.
- Hasta 2015, NSS fue utilizado en Google Chrome y fue verificado de forma independiente por el equipo de Google (a partir de 2015, Chrome cambió a BoringSSL, pero se mantiene el soporte para el puerto basado en NSS).
Los principales problemas que hicieron que el problema permaneciera sin ser detectado durante tanto tiempo:
- La biblioteca NSS es modular y las pruebas de fuzzing no se realizaron de manera integral, sino a nivel de componentes individuales. Por ejemplo, se verificó por separado el código de decodificación de DER y el manejo de certificados; durante el fuzzing, es posible que se haya obtenido un certificado que provocara la manifestación de la vulnerabilidad en cuestión, pero su verificación no alcanzó el código de validación y el problema no se detectó.
- En la prueba de fuzzing se establecieron restricciones estrictas sobre el tamaño de la salida (10,000 bytes) sin tales restricciones en NSS (muchas estructuras en condiciones normales podrían tener un tamaño superior a 10,000 bytes, por lo que se requerían mayores volúmenes de datos de entrada para identificar problemas). Para una verificación completa, el límite debía ser de 224-1 bytes (16 MB), que corresponde al tamaño máximo del certificado permitido en TLS.
- Concepto erróneo sobre la cobertura del código mediante pruebas de fuzzing. El código vulnerable fue probado activamente, pero utilizando fuzzers que no podían generar los datos de entrada necesarios. Por ejemplo, el fuzzer tls_server_target utilizó un conjunto predefinido de certificados listos, lo que limitó la verificación del código de validación del certificado solo a mensajes TLS y cambios de estado del protocolo.
Fuente: opennet.ru
