2 puntos por GN⁺ 2024-04-13 | 1 comentarios | Compartir por WhatsApp
  • Línea de tiempo de los eventos:

    • 2024.01.19: El sitio web de XZ se movió a GitHub Pages por un nuevo mantenedor (jiaT75)
    • 2024.02.15: Se agrega build-to-host.m4 a .gitignore
    • 2024.02.23: Se introducen dos "archivos de prueba" que contienen etapas de scripts maliciosos
    • 2024.02.24: Se lanza XZ 5.6.0
    • 2024.02.26: Commit en CMakeLists.txt que sabotea la función de seguridad Landlock
    • 2024.03.04: La puerta trasera causa problemas con Valgrind
    • 2024.03.09: Se actualizan dos "archivos de prueba", se modifican funciones CRC y se "corrige" el problema con Valgrind
    • 2024.03.09: Se lanza XZ 5.6.1
    • 2024.03.28: Se descubre el bug, se notifica a Debian y RedHat, y Debian revierte XZ
    • 2024.03.29: Se publica un correo en la lista OSS-security, RedHat confirma que distribuyó XZ con puerta trasera
    • 2024.03.30: Debian detiene las compilaciones e inicia el proceso de reconstrucción
    • 2024.04.02: El desarrollador principal de XZ reconoce el incidente de la puerta trasera
  • Valores hash de las distribuciones de XZ que incluían la puerta trasera:

    • xz-5.6.0: se proporcionan hashes MD5, SHA1 y SHA256
    • xz-5.6.1: se proporcionan hashes MD5, SHA1 y SHA256

Análisis inicial de la infección

  • Etapa 1 - script build-to-host alterado:

    • Los archivos fuente de la versión parecían inicialmente inofensivos, pero al descargarse desde una URL controlada por el atacante incluían un archivo build-to-host.m4 que ejecutaba código malicioso
    • Este archivo .m4 se ejecuta durante la compilación y modifica y descomprime el primer archivo agregado a la carpeta de pruebas
  • Etapa 2 - script de shell inyectado:

    • El script malicioso inyectado por el archivo .m4 verifica si se está ejecutando dentro del proceso de compilación previsto en Linux
    • Usa el archivo good-large_compressed.lzma para ejecutar la siguiente etapa; aunque está comprimido normalmente, los datos descomprimidos contienen datos basura en su interior
    • Extrae 33,492 bytes con los comandos head/tail y desofusca aplicando una sustitución básica con el comando tr
  • Etapa 3 - extracción de la puerta trasera:

    • El script de shell de la última etapa realiza varias comprobaciones para verificar si se está ejecutando en el entorno esperado
    • Extrae el propio código binario de la puerta trasera, oculto en otro offset del mismo archivo good-large_compressed.lzma
    • Extrae el archivo con la herramienta XZ y descifra los datos binarios con una serie de llamadas a head usando un algoritmo similar a RC4
    • Extrae el archivo comprimido con XZ, elimina los bytes iniciales usando valores predefinidos y luego lo guarda como liblzma_la-crc64-fast.o
    • Modifica la función is_arch_extension_supported de crc_x86_clmul.h para cambiar la llamada __get_cpuid por _get_cpuid

Análisis de la puerta trasera binaria

  • Escenario de carga encubierta:

    • XZ usa las funciones lzma_crc32 y lzma_crc64 para el cálculo de CRC, y estas se almacenan en la tabla de símbolos ELF con tipo IFUNC
    • IFUNC se usa para decidir dinámicamente si debe usarse una versión optimizada
    • La puerta trasera se almacena como un archivo objeto, y su objetivo principal es enlazarse durante la compilación con el ejecutable principal
    • El archivo objeto incluye el símbolo _get_cpuid; al quitar un guion bajo del código fuente original, cuando el código llama a _get_cpuid en realidad termina llamando a la versión maliciosa
  • Análisis del código de la puerta trasera:

    • El código inicial de la puerta trasera se invoca dos veces, y la actividad maliciosa real comienza cuando lzma_crc64 IFUNC llama a _get_cpuid
    • Encuentra la dirección GOT para localizar la posición del puntero cpuid y lo reemplaza por el puntero de la función maliciosa principal
    • El objetivo principal es enganchar funciones específicas para poder monitorear todas las conexiones hacia el sistema infectado
  • Comportamiento clave:

    • Tiene como objetivos de hooking funciones de libcrypto como RSA_public_decrypt, EVP_PKEY_set1_RSA y RSA_get0_key
    • Verifica si el proceso actual cumple con los criterios de ejecución y confirma la existencia de un kill switch
    • Usa una estructura Trie para realizar operaciones sobre cadenas
    • Usa 3 o más rutinas de resolución de símbolos para encontrar la ubicación de estructuras ELF Symbol
    • Logra el hooking de funciones abusando de la funcionalidad rtdl-audit para secuestrar las rutinas de resolución de símbolos

Opinión de GN⁺

  • Este artículo muestra muy bien un caso de ataque altamente sofisticado en el que se inyectó malware en software de código abierto. Deja la lección de que las ventajas del open source también pueden ser explotadas en su contra.

  • Los ciberataques y las puertas traseras dirigidas a sistemas Linux son cada vez más sofisticados. En particular, los ataques a través de servidores SSH pueden convertirse en una amenaza de seguridad grave.

  • Por otro lado, también demuestra la capacidad de autocorrección del ecosistema open source. Al final, la puerta trasera fue descubierta por la comunidad y se respondió rápidamente. La transparencia es clave.

  • El uso de técnicas como estructuras Trie avanzadas, Symbol Resolver y hooking con dl_audit muestra la evolución técnica del malware para Linux. También hace falta poner especial atención a la seguridad de los sistemas Linux.

  • Cuando una empresa adopta software de código abierto, no solo debe revisar las licencias, sino también validar la seguridad. Es indispensable comprobar si proviene de una fuente confiable y si existe monitoreo continuo del código.

1 comentarios

 
GN⁺ 2024-04-13
Opinión de Hacker News

Resumen:

  • Dado el gran esfuerzo que el atacante puso en los scripts y en el código para evadir la detección, es posible que todo este proyecto funcione como una alternativa a una transición o a varios esfuerzos que avanzaban en paralelo
  • Hay que considerar que enfocarse en SSHD podría afectar otras partes del sistema en su conjunto, así como aspectos técnicos y sociales
  • Podría ser una medida de refuerzo útil que cada biblioteca de enlace dinámico tenga su propia GOT y que, una vez completado el enlace dinámico, la tabla se marque como de solo lectura
  • El código fuente parece haber sido generado ejecutando un desensamblador, entendiendo qué hace el código y luego renombrando todo con nombres descriptivos
  • El retraso y la lentitud en SSH causados por un bug del backdoor terminaron exponiéndolo, y surge la duda de si ya se hizo un análisis sobre eso
  • El repositorio de xz ha reaparecido en GitHub, y los mantenedores están haciendo tareas de limpieza, como eliminar el soporte de ifunc y hacer commits de código que genera archivos de prueba
  • La idea de que probablemente haya muchos backdoors que la gente no ha descubierto, junto con el deseo de que no haya otros tan discretos como este