▶ Lo que debemos sacar del XZ Backdoor 🦎

Lo que debemos sacar del XZ Backdoor

Se ha escrito mucho sobre XZ Backdoor en las últimas semanas, por lo que es hora de mirar hacia adelante. Antes de hacerlo, compartimos más detalles sobre lo sucedido con respecto a openSUSE. Para obtener una descripción general de cómo afectó a los usuarios de openSUSE, consulte la publicación anterior.

Entre bastidores

Unos días antes de la divulgación pública de la puerta trasera XZ, el equipo de seguridad del producto SUSE recibió un indicio de que hay algo extraño con las versiones XZ 5.6.x. Soy el empleado de SUSE y el empaquetador de openSUSE que estaba actualizando e incluyendo esta versión en openSUSE Tumbleweed, así que me involucré en esto bastante temprano. En ese momento, no teníamos a nuestra disposición ningún contexto ni información que se compartiera en la divulgación pública inicial. Sin embargo, esa pista era toda la información que necesitábamos. Cambió la forma en que veíamos un proyecto central de código abierto establecido. Sin eso, las pequeñas diferencias en la etapa de “configuración” del sistema de compilación se habrían ignorado fácilmente.

Un día antes de la divulgación, el jueves por la noche, la seguridad del producto SUSE recibió un informe más largo y detallado de Andrés Freund a través de la lista de divulgación de seguridad de distribuciones compartidas. La lista de distribuciones es una lista de correo cifrada donde los distribuidores colaboran y coordinan la divulgación de problemas de seguridad. Este informe aportó nuevos conocimientos de que la puerta trasera XZ apuntaba específicamente a OpenSSH, que es una de las partes de red de casi todos los sistemas Linux. Esto aumentó aún más nuestro nivel de amenaza hasta convertirlo en una puerta trasera de acceso remoto y también nos hizo ampliar nuestros esfuerzos de comunicación planificados.

El equipo de seguridad de SUSE y yo comenzamos a analizar. La seguridad de productos SUSE es miembro de varios foros de seguridad privados, como la lista de distribuciones y CERT VINCE y otros, que nos permiten coordinar correcciones entre proveedores de software y tener actualizaciones listas en las fechas de divulgación. Con la información inicial de que hay algo sospechoso, fue relativamente fácil encontrar más cosas sospechosas sin ningún orden en particular:

  • openSUSE y SUSE rastrean las firmas de artefactos de lanzamiento con un conjunto de claves de firmas confiables. Notamos que la clave con la que se firmaron los artefactos cambió hace algún tiempo, por lo que tuvimos que actualizar nuestro conjunto de claves confiable para el proyecto XZ. Validamos que hubo un traspaso del mantenedor y que el nuevo mantenedor tiene acceso directo a la confirmación, así como la capacidad de firmar lanzamientos y publicarlos. La red de confianza de esta nueva clave de firma no estaba bien conectada, lo que podría haber dado una alerta, pero estaba firmada por el mantenedor anterior y eso fue suficiente para nosotros.

  • Al observar el historial de confirmaciones, hubo una avalancha de confirmaciones entre la última versión 5.5 beta y la versión 5.6.0 en un corto período de tiempo por parte de ese nuevo mantenedor; no viene a través de una solicitud de extracción y no hay una revisión o discusión obvia al respecto. Esto fue inmediatamente preocupante. Normalmente los proyectos no hacen eso justo antes de un nuevo lanzamiento importante. La revisión de cada confirmación mostró inmediatamente que se estaban confirmando y actualizando archivos de prueba extraños en 5.6.1, y que no tenían las actualizaciones correspondientes en el marco de prueba o en el código del proyecto, por lo que estaban "no utilizados". Normalmente, los archivos de prueba se confirman junto con una corrección de código en la misma confirmación, o con una referencia a un problema anterior o una confirmación que aborda el caso de prueba. Para un mantenedor experimentado de un proyecto upstream, esto parecía un gran descuido. Los mensajes de confirmación eran algo plausibles pero realmente no tenían sentido, especialmente al comparar las (pequeñas) diferencias entre 5.6.0 y 5.6.1.

 Una investigación más profunda condujo a encontrar la "etapa cero" integrada en el sistema de construcción y con eso pudimos atravesar las capas de ofuscación para desenredar la segunda y tercera etapa. En cuestión de minutos, nos quedó claro que se había invertido un esfuerzo muy importante en desarrollarlo. No fue obra de un solo desarrollador en una tarde lluviosa de domingo. Además, la segunda etapa insinuó que se trataba de una puerta trasera dirigida específicamente a entornos específicos, compilaciones de paquetes Debian o RPM que utilizan GCC y glibc. Un usuario normal que construye desde la fuente, ya sea desde el tarball con puerta trasera o desde git, nunca se habría visto afectado. Esto hizo saltar las alarmas. Entonces, antes de continuar con la ingeniería inversa, evaluamos el impacto.

Durante un tiempo, openSUSE no ha estado usando XZ para la compresión de nuestros paquetes rpm de distribución; Nos cambiamos a Zstd hace un tiempo. Sin embargo, XZ se usa ampliamente en la distribución, entre muchas otras cosas para descomprimir las fuentes de nuestro compilador GCC que usamos para construir todo lo demás en la distribución. Verificamos y vimos que la versión XZ presuntamente maliciosa se estaba utilizando para crear nuestro compilador activo openSUSE GCC, que se utiliza en todas las demás versiones de la distribución. El peor escenario en el que pensar aquí es que el XZ malicioso estaba modificando el descomprimido de las fuentes de compilación del compilador GCC y tenemos un compilador del sistema que ya no era confiable. Aunque tenemos comprobaciones de firmas en las fuentes (y tenemos copias seguras de cada fuente de entrada que alguna vez utilizamos en cualquier lugar en un almacén confiable), no tenemos comprobaciones de si las fuentes descomprimidas son en realidad las fuentes cuyas firmas se verificaron antes de descomprimirlas.

Entonces, incluso sin más información sobre la puerta trasera, entendimos que el peor de los impactos podría ser desastroso. Entonces comenzamos a identificar proyectos, productos y distribuciones afectados. Afortunadamente esa lista resultó ser bastante pequeña. Se formó un equipo ad hoc para encargarse de la eliminación de la puerta trasera.

Eliminación inicial de la puerta trasera para nuestros usuarios

openSUSE Tumbleweed incluye un canal de actualización de emergencia que podemos usar para recuperarnos de regresiones fatales en las instantáneas normales de Tumbleweed. Estos son extremadamente raros gracias a nuestro proceso de pruebas automatizadas, pero suceden. Inyectamos una degradación de XZ en ese canal de actualización de emergencia y comenzamos a crear una versión provisional de openSUSE que eliminaba la actualización maliciosa de XZ. Sin embargo, debido a la naturaleza desconocida de la puerta trasera ofuscada, estábamos planeando con la peor suposición. Comenzamos a recopilar cuántos paquetes se crearon y publicaron con la compilación del compilador GCC sospechoso dentro del entorno de compilación. Era una lista muy grande. Además, entender la reversión del código objeto de puerta trasera maliciosa en Ghidra nos llevaría un par de horas más. Después de una breve sincronización, decidimos optar por la ruta segura y desechar todos los paquetes que se crearon con XZ/GCC potencialmente malicioso y comenzamos a reconstruirlos todos solo con paquetes que provenían de una copia de seguridad segura, para restaurar la integridad de nuestro distribución lo más rápido posible. openSUSE prueba regularmente este "modo de arranque" como parte del desarrollo de nuestra distribución y se basa en la automatización de reconstrucción proporcionada por Open Build Service, por lo que no fue mucho trabajo humano. Fue simplemente mucha carga para nuestro clúster de compilación. Tuvimos un par de horas de espera por delante, lo que permitió un análisis más detallado de la puerta trasera.

Análisis de la puerta trasera.

El análisis del código objeto resultó requerir mucho tiempo. Si bien la segunda etapa que verificó las condiciones de compilación correctas (si es una compilación de distribución, si tiene el entorno de compilación esperado, etc.) fue fácil de decodificar y nos ayudó a comprender el impacto potencial, inicialmente no nos quedó muy claro qué estaba funcionando el código objeto ofuscado que se inyectó durante la compilación.

Al usar Ghidra, pudimos recuperar un código C algo legible a partir del código de máquina inyectado, por lo que comenzamos a intentar descifrar el rompecabezas. Uno de los primeros hallazgos fue detectar el punto de entrada en la _get_cpuid función que formaba parte del manejo de IFUNC. Simplemente buscar en Google esta combinación de palabras llevó a una discusión ascendente, a la desactivación de ifunc en el proyecto oss fuzz y a un interesante informe de error en la comunidad Fedora donde se informaron problemas de Valgrind con XZ 5.6.0 y aparentemente el ascendente los estaba solucionando mediante la actualización. cosas no relacionadas, incluidos "los archivos de prueba" en el repositorio. No solo hubo confirmaciones en el repositorio, sino también comunicación engañosa sobre el problema directamente relacionado con esas confirmaciones, lo que hizo obvio que no estábamos encontrando un accidente desafortunado por parte de un mantenedor inocente que podría haber sido pirateado, sino una acción planificada por el actual. mantenedor aguas arriba. En caso de que las alarmas no fueran lo suficientemente fuertes ya, esto duplicó su nivel de ruido.

Preparación para la divulgación pública

Combinando todo lo que hemos aprendido hasta ahora, el panorama se volvió más claro. Alguien había pasado años de preparación para sentar las bases, construir una buena reputación como mantenedor, hacerse cargo del proyecto y luego eligió un momento que era una ventana crítica para varios proyectos de distribución y también en medio del Año Nuevo Lunar. como otros días festivos para lanzar una nueva versión con nuevas características y una puerta trasera ofuscada que estaba bien diseñada para apuntar solo a distribuciones específicas, es decir, aquellas que usan GCC, Binutils, Glibc con RPM o procesos de compilación de Debian en x86_64.

Con todo eso en mente, nos dimos cuenta de que va a haber mucha cobertura pública sobre esto. Estará en las noticias durante días o semanas. Entonces comenzamos una nueva línea de trabajo para prepararnos para eso con los equipos de comunicaciones.

Revelación pública

En el momento de la divulgación pública, todos los flujos de trabajo ya se habían completado. Identificamos la lista de productos afectados y ya habíamos publicado todas las actualizaciones para todos los afectados. La comunicación estaba lista para publicarse en línea y enviarse a las partes pertinentes. Todo eso fue posible porque muchas personas hicieron todo lo posible, dejaron todo lo demás a un lado para reaccionar oportunamente y con mucho compromiso para garantizar que no nos hayamos perdido ni pasado por alto nada; todo ello mientras ya había comenzado un largo fin de semana festivo. Felicitaciones a todos los que trabajaron día y noche para prepararse para esto.

Héroe de la historia

Que no haya sucedido nada peor es sólo gracias a Andrés Freund, un desarrollador de la comunidad PostgreSQL que no se saltó una extraña regresión en el rendimiento de los inicios de sesión SSH en su instalación inestable de Debian recientemente actualizada. Otro testimonio de que no dejar pasar algo que todos los demás probablemente habrían ignorado durante los siguientes meses o años es lo que hace que un héroe sea un héroe.

Sin embargo, confiar en héroes no es una estrategia sostenible y confiable. Entonces, para el futuro, todos debemos aprender de lo sucedido y convertirnos en un gran equipo de pequeños héroes.

TLDR de lo que pasó

Se abusó de las distribuciones de Linux para ofrecer una puerta trasera a sus usuarios. Cuál era el propósito exacto de la puerta trasera aún es una especulación. Todo podría provenir de un individuo que quisiera vender acceso a abundante potencia informática a través de máquinas virtuales alojadas en la nube pública que tienen un puerto ssh vulnerable abierto al público. Este es el extremo del espectro, bastante improbable, pero aún posible. El otro extremo del espectro es una empresa que vende puertas traseras a actores estatales que las utilizan para acceder de forma remota y encubierta a cualquier máquina Linux. Aunque se cometieron errores, casi logró ese objetivo. ¿Dónde está la verdad? Es necesario identificar y analizar más evidencia al respecto.

Es hora de mirar hacia adelante

Después de esta mirada cercana detrás de las cortinas de lo que sucedió a finales de marzo, el resto de esta publicación cambia a mirar hacia adelante.

Ley de Linus y las distribuciones

Con suficientes ojos, todos los errores son superficiales ”. En las comunidades de código abierto, esto se cita mucho como una de las razones por las que se puede confiar en el código abierto. Para los proyectos de código abierto que están atrayendo suficiente atención de contribuyentes suficientemente capacitados, esta “ley” probablemente tenga al menos cierto peso. Sin embargo, de Heartbleed aprendimos, por ejemplo, que estas condiciones previas no se cumplen universalmente. Hay muchos proyectos que son absolutamente esenciales y, sin embargo, se consideran aburridos y no logran atraer a muchos mantenedores o contribuyentes, y aquellos que están en el proyecto ya están enterrados bajo una pila de trabajo y realmente no pueden dedicar un esfuerzo significativo a mejorar. nuevos miembros.

La puerta trasera XZ fue diseñada para apuntar únicamente a distribuciones. En primer lugar, por las comprobaciones previas que ejecutaba la puerta trasera antes de desplegarse, pero también porque las condiciones necesarias para la implantación sólo existían aguas abajo en estas distribuciones. Debian, así como otras distribuciones afectadas, como openSUSE, incluyen una cantidad significativa de parches exclusivos para proyectos esenciales de código abierto, como en este caso OpenSSH. En retrospectiva, ese debería ser otro aprendizaje a nivel de Heartbleed para el trabajo de las distribuciones. Estos parches construyeron los pasos esenciales para integrar la puerta trasera y no tienen el escrutinio que probablemente habrían recibido por parte de los respectivos encargados de mantenimiento. Ya sea que confíes en Linus Law o no, ni siquiera se le dio la oportunidad de intervenir aquí. Upstream no falló en los usuarios, las distribuciones fallaron en upstream y sus usuarios aquí.

El código abierto y sus comunidades

Ser capaz de inspeccionar el código fuente de software de código abierto brinda a la comunidad una ventaja inmejorable sobre las alternativas patentadas de un solo proveedor. Sin embargo, auditar el código fuente requiere mucho tiempo y, a menudo, requiere expertos en seguridad y dominios con mucha experiencia. Las distribuciones comerciales deberían y están jugando un papel importante en esto; todavía no han identificado esto. En ese sentido, el proyecto XZ fue el punto ciego perfecto sobre cómo se suele asignar el esfuerzo a las auditorías de seguridad. Muy profundamente anidado e importante para cada distribución debido a razones no obvias, y en el estado de un solo mantenedor y muy pocos contribuyentes o revisores durante años. No es el nuevo y brillante proyecto de código abierto nativo de la nube o el nuevo y sofisticado proyecto de código abierto que atrae a miles de desarrolladores o investigadores de seguridad y, sin embargo, es igualmente importante para la integridad y seguridad de la informática moderna. Si algo hay que aprender aquí es que los criterios de selección sobre dónde centrarse deben ajustarse con estos aprendizajes.

Además, otros ya han enfatizado que el vector de ataque inicial no fue técnico. No era un tarball arcaico. El ataque inicial real fue ingeniería social y utilizó comportamientos tóxicos en las comunidades. Esto es real y no sólo en este caso afecta a los mantenedores existentes de proyectos de código abierto. Se han contado muchas historias en las que el estrés o el agotamiento de los mantenedores estaban relacionados con participantes tóxicos en las comunidades del proyecto. Aunque creo que las distribuciones no son parte de esas actividades, no estamos preparados para evitar que estas cosas sucedan. Los desarrolladores de la distribución se centran en sus problemas y en sus usuarios y, debido a su tiempo limitado, corren el riesgo de descuidar a las comunidades de código abierto (upstream). Esta es otra cosa que debemos tener en cuenta.

Se han fundado iniciativas como CHAOSS y la Open Source Security Foundation porque, de lo contrario, sería muy fácil pasar por alto estas situaciones. Proporcionan un servicio esencial para analizar el “factor bus” o el “factor de colusión” de cuántos actores se necesitan para subvertir un proyecto y así permitir que otros se concentren en dirigir la ayuda hacia donde más importa.

El costo de la libertad

FLOSS no tiene que ver con el costo ni con el libre uso, sino con la libertad de inspeccionar y (re)usar. ¿Cuál es el costo de esa libertad? En el mundo propietario, el software se paga. En el código abierto, esta libertad necesita recibir el reconocimiento que merece y debe ser valorada. Cuando alguien se refiere a la puerta trasera XZ como un incidente de seguridad de la cadena de suministro de software, esa no es la imagen completa. Una cadena de suministro de software sería aquella donde hay un proveedor en un extremo. Pero los proyectos y las comunidades de código abierto no son proveedores hoy en día. No tienen ningún contrato legalmente vinculante con ninguno de sus consumidores y no hay intercambio de dinero involucrado. Existe una comunidad, de distintos tamaños, que contribuye y ayuda, ya sea como voluntarios o como trabajadores remunerados. La mayoría de los proyectos no reciben suficiente dinero.

Como pensamiento abierto: ¿deberían las distribuciones desarrollar y gestionar activamente su cadena de suministro y tratar a “sus proveedores” como proveedores reales con términos y condiciones mutuos legalmente vinculantes y compensaciones acordadas?

La Secure Web of Trust es la nueva seguridad de la cadena de suministro

En este incidente en particular, se utilizaron archivos comprimidos firmados para publicar el iniciador de la puerta trasera. Se han dicho muchas cosas sobre eso. Necesitamos darnos cuenta de que esto es una distracción. Una trampa. En términos de tamaño del código, el 99,9% de la puerta trasera estaba en el repositorio de código fuente. El lanzador en el tarball debía limitar la exposición de la puerta trasera solo a las víctimas previstas, técnicamente no era necesario para nada ni para nada. Habría sido igualmente fácil de incrustar e igualmente difícil de detectar, ya que el resto del 0,1% también se habría comprometido dentro del repositorio de código del proyecto, sólo que de una manera ligeramente diferente.

Para la mayoría de los demás escenarios de ataque imaginables, los artefactos de lanzamiento firmados proporcionan cualidades importantes. Cumplen con la expectativa de enviar únicamente lo que se considera listo para enviar. Proporcionan una cadena verificable de forma independiente hasta el origen (el “Proveedor”). Sin embargo, cada distribución comienza con esta primera parte verificable de la cadena y luego se suma a la parte superior. A menudo (o mientras tanto casi siempre) también con una forma transparente de verificar esos cambios (en forma de procedimientos conformes a SLSA), todo de forma aislada. ¿Qué tan confiables son esas cadenas inconexas? Actualmente, las distribuciones ocasionalmente reutilizan parches iguales o similares además de las versiones de proyectos anteriores, pero por lo demás, en su mayor parte funcionan de forma aislada y rara vez colaboran activamente. La pieza esencial del parche downstream que activó la puerta trasera existió durante casi 10 años en las distribuciones, pero no se ha visto en upstream.

Reconocemos que la puerta trasera del XZ está construida de forma inteligente. Sin embargo, tuvo sorprendentes fallas en la ejecución. Quien esté interesado en incorporar más puertas traseras habrá aprendido de la amplia cobertura pública de todo lo que salió mal. Estos errores han sido señalados, publicados y aprendidos de ellos. Hemos brindado a los actores detrás de esta puerta trasera capacitación gratuita para futuros ataques. Es hora de que las distribuciones también aprendan de esto y también reciban lecciones de capacitación. Necesitamos colaborar activamente y construir una red de confianza sólida y confiable con proyectos de código abierto y entre nosotros para estar preparados para manejar los inevitables desafíos futuros que vendrán. ¡Construyamos juntos una red segura de confianza!.

Articulo original de openSUSE en ingles.