ClickCease Una inmersión profunda en el compromiso xz

Tabla de contenidos

Únase a nuestro popular boletín

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.

Una inmersión profunda en el compromiso xz

Joao Correia

2 de abril de 2024 - Evangelista técnico

xz es un paquete ampliamente distribuido que proporciona compresión sin pérdidas tanto para usuarios como para desarrolladores, y se incluye por defecto en la mayoría, si no en todas, las distribuciones de Linux. Creado en 2009, desde entonces ha publicado numerosas versiones.

Como proyecto de código abierto, está disponible en GitHub. Sin embargo, en el momento de escribir este artículo, al intentar visitar la página del proyecto página del proyecto aparece un mensaje que dice que "este repositorio ha sido desactivado debido a una violación de los términos del servicio" en lugar de la página tradicional de GitHub. Esta violación se debió a la distribución de malware. En este artículo, nos adentramos en el qué, el por qué, el cómo, y quizás incluso el "quién" detrás de este incidente.

Cuando la noticia saltó a la luz a finales de la semana anterior a Semana Santa, la esfera de la ciberseguridad en Twitter explotó, y los investigadores de Internet se obsesionaron con cada detalle. Este artículo se basa en gran medida en la información recopilada y publicada por estas investigaciones, gran parte de la cual está consolidada aquíy en información obtenida a través de la propia investigación del autor. En la medida de lo posible, se han incluido enlaces a las fuentes originales y, cuando no hay una fuente directa, el lector puede suponer que la información procede del gist de gist de GitHub que recapitula el acontecimiento o de esta cronología.

Hay que tener en cuenta que esta historia es muy reciente. Aún quedan algunos aspectos por resolver, y se insinúa la posibilidad (poco probable) de que la persona que en un principio se creyó que estaba detrás del incidente no sea necesariamente así. Esto se trata con más detalle en la sección de advertencias de este artículo.

Abróchate el cinturón, la madriguera del conejo es profunda en este caso.

 

Contexto histórico

 

El proyecto xz, como muchos otros proyectos de código abierto, nació como el proyecto favorito de un único desarrollador que tuvo una idea y la compartió con el mundo. En 2009, Lasse Collins, anteriormente responsable del mantenimiento de lzma-utils, otro proyecto relacionado con la compresión, creó xz. Fue diseñado como una extensión, o evolución, de lzma, hasta el punto de que liblzma ahora se distribuye como parte del paquete xz por defecto.

Como es habitual en la mayoría de los proyectos unipersonales, el autor era responsable de la mayor parte del código y de gestionar los commits ocasionales de terceros, integrar el código en el repositorio y publicar nuevas versiones. A medida que el proyecto fue ganando atención, la carga de la gestión se hizo más pesada y, con el tiempo, se reconocieron los esfuerzos de otros colaboradores y se les concedieron permisos para gestionar tareas como la revisión del código, la aceptación o el rechazo de envíos y la gestión del repositorio.

Hace poco más de dos años, Jia Tan, un desarrollador que ya había contribuido anteriormente al proyecto, obtuvo permisos de commit y, posteriormente, de gestión de versiones. En retrospectiva, el proceso de añadir un nuevo mantenedor parece haber sido parte de una campaña de ingeniería social dirigida a Lasse Collins. La cronología de estos intercambios de correos electrónicos puede verse aquí.

A través de presiones y acusaciones de abandono del proyecto o pérdida de interés, varios usuarios diferentes (o quizá un único individuo detrás de varios nombres de usuario) enviaron mensajes a la lista de correo del proyecto. Se quejaban de retrasos en la aceptación de parches, la publicación de nuevas versiones y la adopción de métodos diferentes hasta que el responsable del proyecto empezó a confiar en un nuevo, pero entusiasta, colaborador. Las cuentas de correo electrónico detrás de estas tácticas de presión parecen no tener ninguna presencia en Internet más allá de esa lista de correo.

Decir que xz es ampliamente utilizado es quedarse corto. xz es uno de los formatos de compresión que se pueden utilizar para empaquetar el Kernel de Linux en un sistema, lo que lo hace indispensable para arrancar dicho sistema. Los ratios de compresión alcanzados y la velocidad de descompresión lo convierten en una opción perfecta para liberaciones que ocupan poco espacio, imágenes del kernel y otros componentes.

 

El tiempo perdido

 

En un irónico giro del destino, un ingeniero de software de Microsoft, Andres Freund, estaba realizando mediciones de temporización en máquinas virtuales Linux para establecer una línea de base para una tarea no relacionada. Empezó a notar cierto "ruido" en las lecturas. El proceso sshd, responsable de aceptar conexiones shell seguras remotas, estaba utilizando una cantidad excesiva de CPU incluso en intentos de conexión fallidos, con un retardo de 500 ms que afectaba a las conexiones. Este retraso inexplicable llevó a Freund a investigar más a fondo, utilizando herramientas de monitorización del rendimiento (perf) y depuración (dbg) para identificar el problema.

Él descubrió una puerta trasera en xz. Específicamente, identificó la puerta trasera y el código inyectado, ya que la puerta trasera operaba a cuestas de ciertas funciones llamadas por sshd. Es importante señalar, y puede que los lectores más avispados ya lo sepan, que sshd no depende de xz ni de liblzma. Sin embargo, en los sistemas que utilizan systemd para cargar sshd, systemd incluye liblzma como dependencia. Esta conexión permitió introducir el código backdoor en sshd. Los sistemas que entran en esta categoría incluyen Fedora, Ubuntu, Debian y la mayoría de sus distribuciones derivadas.

 

La puerta trasera

 

El método por el que se introdujo el código en xz (y liblzma) consistió en añadir unos cuantos archivos binarios al repositorio de xz y comprometer el proceso de compilación. Estos archivos, originalmente enviados por Jia Tan como parte de un "conjunto de pruebas" para xzeran blobs binarios "hechos a mano con un editor hexadecimal". Leer código fuente ya es una tarea compleja, pero leer código binario es casi imposible. Hay un comentario irónico que dice que "no hay mejor código fuente que los propios archivos". Efectivamente.

El commit que incluía los archivos maliciosos se realizó el 23 de febrero de 2024. Por lo que se sabe actualmente, el código malicioso solo está presente en dos de los archivos binarios, mientras que los demás parecen realizar las funciones previstas: probar diferentes condiciones de fallos en el proceso de compresión o descompresión de xz y liblzma.

Uno de los aspectos destacables de la puerta trasera es que si un usuario cualquiera extrajera el código del repositorio xz y lo compilara después de incluir la puerta trasera, no acabaría con un binario comprometido (por lo que se supone en la actualidad, aunque esto puede demostrarse erróneo más adelante). El código de inyección real sólo se incluiría en la salida si un archivo específico "build-to-host.m4" estuviera presente durante la compilación, pero este archivo también se añadió a ".gitignore", haciéndolo inaccesible a las operaciones regulares de git típicamente utilizadas por los usuarios finales. Sin embargo, se utiliza durante el proceso de compilación del paquete de una distribución Linux.

El objetivo de esta estrategia era introducir el código en distribuciones reales de Linux y, al mismo tiempo, dificultar a los investigadores de seguridad la reproducción del incidente en un entorno controlado.

El 24 de febrero, un día después de añadir los archivos maliciosos, el mismo usuario etiquetó (es decir: presentó como próxima versión) xz-5.6.0. Las distribuciones de Linux suelen recoger nuevas versiones de paquetes y, por ejemplo, Debian la incluyó en el repositorio inestable un par de días después.

El día 28 se añadió un parche adicional de Jia Tan que interfería con la detección de landlock durante el proceso de compilación. Landlock es una característica de seguridad que evita (entre otras cosas) el enlazado e importación de código ajeno que se activaría si se habilitara durante la compilación, por lo que tuvo que ser eludida para que el ataque tuviera éxito.

Esto se logró de una manera muy sutil. Un único "." (punto) añadido a "CMakeLists.txt" interrumpía la compilación de la comprobación del sandbox, haciendo que la detección de landlock devolviera siempre false, lo que, a su vez, la deshabilitaba siempre para el código malicioso. Este cambio no se detectó cuando se envió. Significativamente, Lasse Collins (no Jia Tan) se acredita con este commit, que puede haber sido falsificado, o el cambio muy sutil no fue detectado antes de añadir el código.

En particular, el 29 de febrero, un pull request en el proyecto systemd solicitaba dejar de enlazar liblzma para reducir el tamaño de las imágenes. Esto habría frustrado el ataque. Este evento no parece estar relacionado con el ataque real y se acepta como una coincidencia que puede haber acelerado la línea de tiempo, y se desconoce si las conversaciones previas sobre el tema eran públicas y conocidas por el atacante.

La función que invoca el código malicioso es _get_cpuid. Puede haber otras funciones aún por descubrir. Esta función ejecutaría el código malicioso de carga útil antes de realizar el trabajo original de _get_cpuid y devolverlo, añadiendo la latencia notada por el ingeniero de Microsoft. Más concretamente, esta función se llama al principio del proceso de validación del certificado cuando se inicia una conexión.

Algunas distribuciones empezaron a observar errores de valgrind en esa función durante el análisis. El 8 de marzo, Jia Tan envió código para solucionar las detecciones de Valgrindque, en retrospectiva, parece simplemente desactivar el análisis del código malicioso.

Al día siguiente, el 9 de marzo, Jia Tan actualizó los archivos backdoored, con el pretexto de que "fueron creados con aleatoriedad local a su máquina, y para reproducirlos mejor en el futuro, se debe utilizar un valor semilla constante". Una vez más, los archivos binarios son difíciles de analizar, especialmente cuando el código backdoor se limita a seleccionar valores de ubicaciones predefinidas dentro del blob binario, lo que hace prácticamente imposible su detección. El mismo día, etiquetó y liberó xz-5.6.1.

El 25 de marzo, una de las cuentas de correo electrónico utilizadas para presionar al mantenedor original de xz reapareció, ahora presionando al proyecto Debian para que incluya la nueva versión de xz. Otras cuentas aparentemente fantasmas se unieron para aumentar la presión.

El 28 de marzo, Jia Tan presentó un informe de error a Ubuntu para la inclusión de xz-5.6.1ya que Debian lo había incluido.

El comportamiento malicioso está dirigido específicamente a sistemas x86-64 que ejecutan glibc (depende de una función proporcionada por glibc) y ejecutando sshd a través de systemd. Este conjunto de condiciones coincide con las distribuciones basadas en Debian y Red-Hat.

La desofuscación y el análisis del código malicioso revelaron que se activaba cada vez que se recibía una conexión entrante en sshd. Sólo recientemente se ha descubierto que el código código espera una clave pública concreta al recibir una conexión. Si esta clave no está presente, sshd funcionará como de costumbre. Sin embargo, cuando una clave controlada por el atacante está presente, el código desencadena un comportamiento diferente, controlado remotamente.

 

Detección, y el mundo del código abierto se tambalea

 

El 28 de marzo, la investigación de Andres Freund llevó a la identificación de la puerta trasera. Se notificó a las distribuciones y se publicaron actualizaciones que básicamente retrotraían los paquetes a una versión anterior a la participación de Jia Tan en el proyecto xz. Esto significa que ahora hay una versión "5.6.1+realmente5.4.5" de xz disponible en los repositorios de varias distribuciones.

Hasta ahora, las distribuciones que han reconocido la presencia del paquete comprometido incluyen Fedora Rawhide, Fedora 40 beta y Debian.

Dado que xz desempeñaba un papel crucial en el propio proceso de construcción de paquetes, el proyecto Debian optó por reconstruir todo su sistema de construcción, ya que había estado ejecutando una versión de xz que incluía los parches de Jia Tan (antes de la supuesta inclusión de la puerta trasera).

Un ataque a la cadena de suministro puede tener un alcance asombroso. Aunque esto se afirma a menudo, solo se hace verdaderamente evidente con pruebas claras e inequívocas, como este ataque. 

El análisis de esta situación pone de manifiesto varias cuestiones:

En primer lugar, la forma en que se gestionan los proyectos de código abierto, sin la financiación y los recursos adecuados, lleva a situaciones en las que los responsables del mantenimiento pueden verse abrumados y engañados para que acepten compromisos menos que ideales. Esta vulnerabilidad permite a los agentes de amenazas infiltrarse y, en última instancia, hacerse con el control de proyectos clave.

En segundo lugar, xz fue simplemente el proyecto que quedó atrapado. Si no fuera por el retraso causado por el código malicioso, que probablemente podría haber sido optimizado con más tiempo, este ataque podría no haber sido detectado en absoluto, y todo el mundo estaría ejecutando una versión comprometida de xz en sus sistemas basados en Debian y Red-Hat. Al revertir xz, se asume que esta amenaza en particular ha sido neutralizada. Sin embargo, la certeza de esta afirmación sigue siendo incierta en este momento.

En tercer lugar, el código se añade a los proyectos de código abierto cada minuto de cada día, a través de innumerables proyectos diferentes. La forma en que se utilizan y verifican las dependencias permite que una cascada de desvíos llegue al objetivo previsto, incluso si ningún código malicioso llega a tocar directamente el paquete objetivo del atacante.

En cuarto lugar, el argumento de que el código fuente abierto es más seguro simplemente porque es abierto es un hombre de paja. Este argumento sólo es válido mientras haya personas suficientes y suficientemente motivadas escudriñando cada línea de código, de cada proyecto, en cada commit. Esto requiere un gran número de personas altamente cualificadas, que realicen una cantidad significativa de trabajo no remunerado, indefinidamente. La capacidad de comprobar y examinar el código sólo es eficaz si realmente se realiza la comprobación y el examen. Incluso entonces, por su propia naturaleza y por los métodos de ofuscación disponibles, es posible introducir código malicioso en proyectos desprevenidos. De hecho, se podría argumentar que, desde el punto de vista de la seguridad, la disponibilidad del código fuente también podría ayudar, y quizás en gran medida, a los actores maliciosos que buscan identificar vulnerabilidades, más de lo que ayuda a los usuarios finales. Aunque el código fuente abierto ofrece muchas ventajas innegables, la seguridad intrínseca no siempre es una de ellas. Esta puerta trasera se descubrió totalmente por accidenteno porque alguien estuviera revisando activamente el código.

En quinto lugar, la construcción de una reputación en la comunidad de código abierto a menudo se basa únicamente en el historial de commits en GitHub y nada más. Demostrar interés en un proyecto y contribuir con algunas correcciones de código suele bastar para ser aceptado. Demostrar entusiasmo por ayudar puede ser fácilmente inventado. Esto hace que la identificación de individuos específicos detrás de cuentas esencialmente anónimas sea muy difícil. Un usuario puede tener varias cuentas o crear otras falsas cuando una cuenta resulta sospechosa o se identifica como maliciosa. Una organización con suficientes recursos puede crear y dotar de personal a un ejército de estas cuentas.

En sexto lugar, no suele haber un plan de recuperación ante desastres claramente definido para la mayoría de los proyectos de código abierto. Volver a un buen estado conocido es un reto si es difícil incluso determinar cuál es ese buen estado conocido. Aunque se culpa a una cuenta de este ataque, no se sabe con certeza si fue la única utilizada.

 

La posible advertencia

 

Del análisis de cómo se desarrolló este incidente, todo parece indicar la participación de un actor o grupo de amenaza bien financiado y altamente cualificado. Algunas observaciones dignas de mención son:

 

  • Jia Tan parece seguir un horario laboral de 9 a 5 (o 6). Los commits y la actividad en GitHub sugieren este patróny los fines de semana y días festivos propios de ciertos países son evidentes a simple vista. Sin embargo, es importante tener en cuenta que las marcas de tiempo en los commits de git pueden manipularse a voluntad, y -comparado con el nivel de pericia demostrado en el código de la puerta trasera- alterar la hora de un commit es trivial.
  • Jia Tan ha contribuido con código a múltiples proyectos fuera de xz. De hecho, la cuenta incluso ha enviado código a Google's OSS-Fuzzde Google, una herramienta diseñada para identificar comportamientos maliciosos o con errores en proyectos de código abierto, así como en otros proyectos relacionados con la compresión. Todo este código está ahora bajo escrutinio y ya no es de confianza.
  • Curiosamente, la zona horaria de los commits en los que se subieron los archivos maliciosos difiere de la zona horaria típica asociada a la cuenta de Jia Tan. Se puede encontrar un análisis detallado de esta incoherencia aquípero plantea la posibilidad de que la cuenta del desarrollador se haya visto comprometida en lugar de haber sido utilizada intencionadamente. Aunque sigue siendo una posibilidad, otros aspectos del incidente la hacen menos plausible. No obstante, es un punto a considerar.

 

Observaciones finales

 

Es probable que esta historia esté lejos de terminar. La respuesta hasta ahora ha consistido en cerrar el repositorio GitHub de xz, revertir los paquetes de distribución a una versión anterior y reevaluar otros commits del supuesto usuario responsable.

 

Las preguntas abiertas incluyen:

 

  • Se trata de uno de los ataques a la cadena de suministro más sofisticados hasta la fecha. Es difícil concebirlo como obra de un solo hacker. ¿Quién estaba detrás? Si Jia Tan cumplía un horario de trabajo, ¿qué país, organización o grupo le pagaba el sueldo?
  • Mantener una operación durante más de dos años requiere recursos y esfuerzos considerables. ¿Cuál era el objetivo final? Al final, todos los sistemas basados en Debian y Red Hat se habrían visto comprometidos. ¿Quién se beneficiaría de tener acceso a todos los sistemas con esas distribuciones?
  • La hora y las zonas horarias se manipulan fácilmente en los mensajes de confirmación. ¿Se han configurado intencionadamente para que apunten a zonas específicas?
  • ¿Se ha identificado todo el código malicioso? ¿Hay más carga útil por descubrir?
  • ¿Era sshd el único proceso objetivo?
  • ¿Qué otros proyectos se han visto afectados por el atentado?

 

En ciberseguridad, esquivamos balas constantemente. Hasta que dejamos de hacerlo. Y lo curioso es que ni siquiera veremos la que nos alcance hasta que sea demasiado tarde.

¿Desea obtener más información sobre las vulnerabilidades y exposiciones comunes (CVE) y comprender la importancia de las CVE en la seguridad informática? Vea nuestra LinuxTalk con Tuxcare Youtube Serie EP2

Profundice en el reciente compromiso de xz, descubra qué ocurrió, cómo ocurrió y sus implicaciones para la comunidad de código abierto en nuestra Charla Linux con TuxCare Youtube Seie Ep 4

Resumen
Una inmersión profunda en el compromiso xz
Nombre del artículo
Una inmersión profunda en el compromiso xz
Descripción
xz fue desactivado debido a una violación de las condiciones del servicio. Veamos el qué, el por qué e incluso el "quién" está detrás de este incidente.
Autor
Nombre del editor
TuxCare
Logotipo de la editorial

¿Desea automatizar la aplicación de parches de vulnerabilidad sin reiniciar el núcleo, dejar el sistema fuera de servicio o programar ventanas de mantenimiento?

Más información sobre Live Patching con TuxCare

Conviértete en escritor invitado de TuxCare

Empezar

Correo

Únete a

4,500

Profesionales de Linux y código abierto

Suscríbase a
nuestro boletín