Atacantes envenenaron tres crates de Rust para robar credenciales de desarrolladores durante las compilaciones

Las versiones maliciosas permanecieron en línea entre 86 y 107 minutos en varios paquetes con aproximadamente 264 millones de descargas acumuladas.

By · Published

Primary source: BleepingComputer

Why it matters

Rust build scripts execute with developer privileges during compilation, giving a poisoned dependency access to the credentials, source code, and signing keys used to ship software.

Attackers poisoned three Rust crates to steal developer credentials during builds — The malicious releases remained online for 86 to 107 minutes across packages with roughly 264M lifetime downloads.

Los atacantes usaron la cuenta legítima de publicador de crates.io de David Roundy el 20 de agosto para distribuir malware a través de tres paquetes de Rust ampliamente descargados, convirtiendo una compilación de software ordinaria en ejecución de código en estaciones de trabajo de desarrolladores y sistemas de CI.

Las versiones afectadas fueron arrayref 0.3.10, internment 0.8.7 y append-only-vec 0.1.9, según el Rust Security Response Team. Los administradores de Rust eliminaron las versiones y bloquearon la cuenta de Roundy tras concluir que su computadora o sus credenciales probablemente fueron comprometidas. Indicaron que no creían que Roundy actuara con malicia.

Roundy es físico y desarrollador de código abierto de larga trayectoria que originalmente desarrolló el sistema de control de versiones Darcs. Su CV académico enumera un doctorado en física por la University of California, Berkeley, seguido de puestos de investigación en MIT y Cornell y un nombramiento como profesor en Oregon State University. El ataque explotó la confianza acumulada alrededor del software que había mantenido durante años, en lugar de introducir un paquete desechable y esperar a que los desarrolladores lo encontraran.

BleepingComputer informó que las tres versiones envenenadas aparecieron en un lapso de 23 minutos. Cada una agregó una dependencia a proc-macro1, una imitación controlada por el atacante del legítimo proyecto proc-macro2 asociado con el destacado mantenedor de Rust David Tolnay. Tolnay fue suplantado mediante metadatos de paquete similares y una cuenta llamada dtolney; las investigaciones no indican que su cuenta real haya sido comprometida.

Una línea de dependencia llevó a cabo el ataque

El código fuente ordinario dentro de los crates de Roundy permaneció esencialmente sin cambios. La adición maliciosa fue una declaración de dependencia que apuntaba a proc-macro1 1.0.107, según análisis de StepSecurity, SafeDep y Aikido.

Cargo compiló automáticamente la dependencia declarada, aunque las bibliotecas afectadas no la invocaran. El archivo build.rs dentro de proc-macro1 reconstruyó una dirección de servidor a partir de fragmentos en Base64, deshabilitó la verificación de certificados, seleccionó una carga útil según el sistema operativo y la arquitectura del procesador del host, y la descargó durante la compilación.

El dropper soportaba Linux x86-64, Windows x86-64, macOS x86-64 y macOS ARM64. En sistemas Unix escribió un ejecutable en /tmp/rust-setup y lo lanzó como un proceso desacoplado. En Windows creó un archivo de PowerShell en el directorio temporal y usó un lanzador VBS oculto bajo wscript.exe. La compilación aún podía finalizar correctamente, dejando al desarrollador con la salida habitual del compilador mientras la carga útil seguía ejecutándose.

Investigadores de Wiz analizaron el implante de segunda etapa y encontraron robo de credenciales, persistencia y funciones de comando remoto. Wiz dijo que el malware consultó las bases de datos de inicio de sesión de Chrome, Brave y Edge, transmitió información del host y credenciales robadas, e instaló persistencia mediante una clave Run del Registro de Windows, un LaunchAgent de macOS o un servicio systemd de usuario en Linux. También podía descargar y ejecutar scripts adicionales de shell o PowerShell.

El atacante fabricó una ruta de actualización

La operación comenzó horas antes de que se tocasen los paquetes de Roundy. A la 01:17 UTC, el atacante creó la cuenta lookalike dtolney en GitHub. Una identidad coincidente en crates.io siguió minutos después. A la 01:55, esa cuenta publicó proc-macro1 1.0.106 como una copia aparentemente limpia de proc-macro2, dando al paquete varias horas de historial de publicación antes de que la versión 1.0.107 añadiera el script de compilación malicioso a las 07:11.

Cuatro minutos después, la cuenta de Roundy publicó arrayref 0.3.10. La cuenta luego retiró (yanked) las versiones 0.3.5 a 0.3.9 en rápida sucesión. Los archivos de bloqueo existentes (lockfiles) podían seguir usando una versión retirada, pero Cargo advertiría a los desarrolladores que actualizaran. Un desarrollador que siguiera esa advertencia podría resolver la versión recién publicada 0.3.10, que era la versión envenenada.

La misma cuenta publicó internment 0.8.7 a las 07:34 y append-only-vec 0.1.9 a las 07:37. Un informe público de RustSec siguió a las 07:54. Los administradores del registro eliminaron arrayref 0.3.10 después de 86 minutos, internment 0.8.7 después de 90 minutos y append-only-vec 0.1.9 después de 107 minutos. También eliminaron los paquetes controlados por el atacante proc-macro1, proc-macro-en, aovine, arone, aronenao y tinymember.

StepSecurity estimó que los tres paquetes legítimos tenían aproximadamente 264 millones de descargas combinadas a lo largo de su vida. arrayref representó alrededor de 245 millones de esas descargas y 53.7 millones durante los 90 días previos. Esos totales del registro cuentan descargas, en lugar de desarrolladores únicos, instalaciones o infecciones confirmadas. La población expuesta más limitada consiste en máquinas que resolvieron y compilaron una de las versiones maliciosas mientras estuvo disponible.

El alcance de dependencias sigue siendo sustancial. StepSecurity identificó 406 versiones de crates que dependen directamente de arrayref, incluyendo rutas hacia la biblioteca de hashing blake3, proyectos GUI de Rust como egui, eframe e iced, y componentes usados en software de Ethereum y Solana. Un lockfile preexistente fijado a una versión limpia generalmente evitaría la actualización envenenada. Lockfiles nuevos o actualizados durante la ventana de exposición implicaban mayor riesgo.

Las máquinas de los desarrolladores se convirtieron en el objetivo

Wiz dijo que la infraestructura de comando y control se solapó con infraestructura y técnicas vistas en operaciones de la cadena de suministro atribuidas a actores norcoreanos, incluyendo compromisos anteriormente reportados como Mastra y axios. El solapamiento incluye rangos de hosting, rutas de beacon, certificados y una dirección reportada en otra campaña. Esa evidencia establece una conexión técnica entre operaciones; no identifica de forma independiente quién controló la cuenta de Roundy.

El ataque se concentró en las máquinas que compilan software porque esos sistemas frecuentemente contienen código fuente, sesiones del navegador, credenciales de la nube, tokens de CI, claves de firma y acceso a publicación de paquetes. El implante no necesitaba que la aplicación final se ejecutara. Cargo lo ejecutó mientras preparaba una dependencia, antes de que la funcionalidad de la biblioteca afectada entrara en escena.

El Rust Security Response Team aconsejó a los desarrolladores inspeccionar las cachés de Cargo y los archivos de bloqueo en busca de las versiones eliminadas y de los nombres de paquetes controlados por el atacante. Wiz y StepSecurity también recomendaron comprobar conexiones a 23.254.165.112 en los puertos 9089 y 443 y la presencia de archivos como /tmp/rust-setup, rust-setup.ps1 y rust-setup-launch.vbs.

Cualquier estación de trabajo o runner de CI que compilara una dependencia afectada durante la ventana relevante debe considerarse comprometida. La remediación incluye rotar todas las credenciales accesibles desde la máquina, revocar sesiones de navegador y tokens de CI, reemplazar claves de firma y de publicación, y reconstruir los entornos y artefactos afectados a partir de fuentes conocidas limpias.

Reader comments

Conversation for this story loads after sign-in.