Imagen ilustrativa generada con IA
Tres crates de Rust comprometidos distribuyen malware durante la compilación
El equipo de Rust retiró tres crates comprometidos en crates.io que distribuían malware durante la compilación. Detalles del ataque y medidas de seguridad.
Texto generado por inteligencia artificial, publicado sin revisión humana. Transparencia IA
Tres releases maliciosas retiradas de crates.io
El proyecto Rust retiró de crates.io tres versiones comprometidas de crates ampliamente utilizados: arrayref 0.3.10, internment 0.8.7 y append-only-vec 0.1.9.
Las releases se publicaron el 20 de agosto de 2026 desde la misma cuenta propietaria y permanecieron disponibles entre 86 y 107 minutos:
- arrayref 0.3.10: de
07:15:00Za08:41:40Z; - internment 0.8.7: de
07:34:07Za09:04:11Z; - append-only-vec 0.1.9: de
07:37:49Za09:25:24Z.
El Rust Security Response Team recibió el primer aviso a las 07:15 UTC, tras descubrirse un crate malicioso denominado proc-macro1. El nombre imita al legítimo proc-macro2, una técnica de typosquatting diseñada para pasar inadvertida en los manifiestos de dependencias.
También se consideran comprometidos, en cualquier versión, proc-macro1, proc-macro-en, aovine, arone, aronenao y tinymember.
No se asignó ningún identificador CVE. Las advisories de RustSec no presentan evidencias de uso efectivo de las versiones maliciosas. Tampoco se indica que el incidente figure en el catálogo KEV de CISA.
El ataque se iniciaba con una compilación normal de Cargo
El problema no requería utilizar una función específica de los crates comprometidos. Bastaba con ejecutar cargo build, cargo check o cargo test en un proyecto que resolviera la dependencia alterada.
El manifiesto de las releases incluía una línea adicional para introducir proc-macro1. El crate falsificado contenía el código fuente auténtico de proc-macro2, con el fin de mantener un comportamiento aparentemente normal. El componente malicioso era un script de compilación ejecutado automáticamente durante el build.
El script reconstruía, a partir de fragmentos codificados en Base64, la dirección del servidor de comando y control y la utilizada para descargar el payload. También instalaba un verificador TLS personalizado cuyas tres funciones de validación siempre devolvían un resultado positivo. En la práctica, la verificación de certificados quedaba desactivada.
Después, el código elegía uno de cuatro payloads según el sistema operativo y la arquitectura del procesador. En Unix y macOS, el archivo se escribía en /tmp/rust-setup, se hacía ejecutable y se iniciaba en segundo plano, pasando la dirección C2 como primer argumento.
En Windows se creaban dos archivos en el directorio temporal del usuario:
%TEMP%\rust-setup.ps1;%TEMP%\rust-setup-launch.vbs.
El segundo se ejecutaba mediante wscript.exe en modo oculto. A continuación, el proceso hijo se separaba del job object de Cargo, impidiendo que la compilación esperara a que terminara.
El resultado era una cadena de ataque insertada en la fase de build, antes incluso de ejecutar la aplicación. Se trata de una diferencia sustancial frente a un malware activado únicamente por el comportamiento en runtime del programa.
La retirada de versiones anteriores facilitó la distribución
La publicación de arrayref 0.3.10 estuvo acompañada, en el mismo minuto, por la retirada de las versiones legítimas 0.3.5 a 0.3.9. De este modo, la release maliciosa se convirtió en la única disponible dentro de la serie compatible.
Cargo utiliza intervalos caret para muchas dependencias. Por tanto, una restricción como arrayref ^0.3.6 acepta todas las versiones compatibles de la serie 0.3.x, incluida la 0.3.10. El investigador de GitHub jhobern afirmó haber encontrado el ataque precisamente a través de este mecanismo.
El alcance potencial de arrayref es considerable. Una consulta a la API de crates.io realizada el 21 de agosto de 2026 registró:
- 245.385.500 descargas totales;
- 53.905.601 descargas en los 90 días finalizados el 20 de agosto;
- 403 crates distintos que lo declaraban como dependencia.
Entre las cadenas de dependencias figura winit, que requiere sctk-adwaita ^0.10.1; este último depende de tiny-skia ^0.11, que a su vez requiere arrayref ^0.3.6.
blake3 también dependía de arrayref hasta la versión 1.8.6, pero no de la 1.8.7, publicada a las 09:09 UTC. Los proyectos blake2b_simd y blake2s_simd eliminaron la dependencia en releases publicadas, respectivamente, a las 09:25 y a las 09:26 UTC.
Se desconoce el método utilizado para comprometer la cuenta. El propietario legítimo de arrayref es el usuario de crates.io 2402, David Roundy, registrado en octubre de 2009. El equipo de Rust considera probable que se comprometieran el equipo o las credenciales, y no que se tratara de una acción intencionada del autor.
El payload instalaba persistencia y robaba datos de los navegadores
Según el análisis de Wiz, la siguiente etapa se comunicaba mediante solicitudes HTTPS POST hacia la ruta /49890878. El malware podía instalar mecanismos de persistencia específicos del sistema operativo:
- una clave Registry Run en Windows;
- un LaunchAgent en macOS;
- un servicio systemd del usuario en Linux.
El componente admitía cuatro categorías de comandos: terminación, modificación del servidor C2, instalación de persistencia y descarga y ejecución de scripts adicionales.
Wiz también observó el robo de credenciales de las bases de datos SQLite de Chrome, Brave y Edge. Sin embargo, el análisis de Nextron del payload para Windows solo detectó la lectura de los campos origin_url y username_value, sin extraer directamente password_value.
Los payloads para Linux y macOS solo estaban disponibles en forma de hash y no fueron analizados. Por tanto, no es posible extrapolar automáticamente a ambos sistemas operativos las conclusiones observadas en la muestra de Windows.
La atribución sigue abierta. Wiz señaló solapamientos de infraestructura con campañas norcoreanas anteriores contra la cadena de suministro, incluidos los compromisos de Mastra npm y axios. Microsoft vinculó la operación de Mastra con Sapphire Sleet, mientras que GTIG atribuyó el incidente de axios a MIDNIGHT NEPTUNE, anteriormente identificado como UNC1069.
Sin embargo, ningún proveedor ha atribuido esta campaña en crates.io a un grupo específico.
Qué deben comprobar los desarrolladores
El Rust Security Response Team retiró las releases maliciosas y revocó el estado anterior de yanked para gestionar el incidente. Para arrayref, la recomendación es utilizar la versión 0.3.9 o anterior. No existe una release corregida de las tres versiones comprometidas.
Los desarrolladores deberían:
- revisar
~/.cargo/registry/cacheen busca de los paquetes eliminados; - volver a examinar los proyectos compilados con
cargo build,cargo checkocargo test; - buscar conexiones hacia los indicadores conocidos;
- comprobar la presencia de archivos temporales y mecanismos de persistencia;
- rotar las credenciales que pudieran haberse utilizado en los sistemas afectados.
Los indicadores de red incluyen:
23.254.165.112:9089, servidor utilizado para el payload;23.254.165.112:443, infraestructura C2;hwsrv-798836.hostwindsdns.com.
Los nombres de archivo que deben buscarse son /tmp/rust-setup, %TEMP%\rust-setup.ps1 y %TEMP%\rust-setup-launch.vbs. Entre los binarios se han identificado rust-crate_0.1.0, _0.2.0, _0.3.0 y _0.4.0.
También deben examinarse los metadatos relacionados con las cuentas dtolney, identificada como suplantadora, y droundy, asociada al propietario legítimo. También se señaló la dirección [email protected].
En el caso de arrayref, el incidente está documentado en la advisory RUSTSEC-2026-0260. Cargo todavía no dispone de una ventana de espera predeterminada para las dependencias recién publicadas: el 21 de agosto de 2026 seguía abierta una propuesta para estabilizar global-min-publish-age.
El incidente pone de manifiesto el riesgo de las dependencias actualizadas automáticamente y, sobre todo, de los scripts ejecutados durante la compilación. En un caso anterior, ocurrido en septiembre de 2025, dos crates maliciosos activaban el código únicamente en runtime. Aquí, en cambio, el punto de entrada era el proceso de build, una fase que a menudo se considera más confiable dentro de la cadena de software.
Fuentes
Este artículo es una reelaboración original basada en las siguientes fuentes.
