El comando se llamaba aipoison
Socket encontró un clúster de 18 paquetes npm que suplantaban el scope privado @ali de Alibaba. Ninguno de los tarballs contenía malware. El RAT se armaba en el momento de la instalación a partir de un archivo JSON en un repositorio de GitHub que el atacante aún controla, y su plan de persistencia incluía parchear Python dentro de los directorios .skills de las herramientas de código con IA, con comandos llamados aipoison, aipoison_inject y aipoison_deploy. Leer el código no podía encontrar esto. Bromure Agentic Coding juzga lo que estuvo visible todo el tiempo: un paquete sin reputación se detiene a esperar tu consentimiento en el proxy del host, las tres descargas que arman el payload cruzan un cable que solo habla con destinos que tú aprobaste, y cada archivo que el RAT escribe cae en una VM que vive una tarea.
En algún lugar del payload final hay un comando llamado aipoison. Su
trabajo es meterse en el directorio de skills de tu herramienta de código
con IA y parchear un archivo Python, para que la próxima vez que te
pongas a trabajar, el atacante también empiece.
El 3 de agosto de 2026, The Hacker News
cubrió la investigación que Socket publicó a finales de julio:
un clúster de unos dieciocho paquetes npm, preparados a finales de abril,
que pasaron tres meses en el registro antes de que alguien los detectara.
Suplantan los paquetes privados de Alibaba bajo el scope @ali publicando
los mismos nombres sin scope (aone-cloud-cli, def-open-client,
open-worker-cli, uniapi-bridge), de modo que un desarrollador o un
build dentro de la organización objetivo resuelve el doble público y recibe
un troyano de acceso remoto injertado en el árbol de dependencias. Karlo
Zanki, investigador de Socket, lee el móvil como espionaje industrial.
Nada en los paquetes era malicioso
Abre cualquiera de esos tarballs y no encuentras nada que reportar. No hay
hook de postinstall, lo primero que todo el mundo busca con grep. Los
paquetes señuelo dependen de smart-config-manager, que depende de
cloud-config-fetcher y local-config-parser. Un gestor de config, un
fetcher, un parser: utilidades aburridas, cada una legible en un minuto.
La malicia vive en la composición, y en un archivo que el atacante nunca
envió. Al importar, el fetcher descarga defaults/preferences.json desde
un repositorio de GitHub que el atacante controla, y sigue controlando, y
lo escribe en disco como .cloud-preferences.json. El parser evalúa las
“reglas de transformación” de ese archivo dentro de un vm de Node, que es
donde vive el ataque. Una de las reglas es un escape de sandbox con
estatus de folclore:
var F = items.constructor.constructor; // recover Function
var p = F('return process')(); // recover process
Desde process baja por una escalera de alternativas
(getBuiltinModule, mainModule.require,
mainModule.constructor._load) hasta que una de ellas entrega require en
la versión de Node donde haya aterrizado. Luego descarga setting.js desde
un bucket de almacenamiento de Alibaba Cloud, que toma la huella del host e
instala el payload: en Windows, matar Alilang, la app de seguridad de la
propia Alibaba, y reemplazar su app.asar por una copia troyanizada; en
Linux, soltar un binario en /tmp, ejecutarlo desacoplado, borrar el
archivo; en macOS, inyectarse en ~/.zshrc y registrar un LaunchAgent que
se dispara cada diez minutos.
GBHackers puso el diseño en su titular: los atacantes repartieron el RAT entre paquetes para evadir revisiones de código aisladas. El atacante construyó esta campaña para sobrevivir a que alguien la leyera. Revisa cualquier paquete por separado y pasa. Revisa el árbol completo y sigue pasando, porque la parte hostil es un archivo JSON en un servidor, descargado después de que terminaste de revisar, editable por el atacante entre tu auditoría y tu instalación.
El plan de persistencia incluye a tu agente
Socket recuperó el payload final como aone-cli. Hace lo que hacen estas
cosas: comandos de shell, subida y descarga de archivos, reconocimiento del
host, capturas de pantalla, un proxy TCP inverso cifrado y un comando
dws_lateral que se mueve por DingTalk. Su tráfico de C2 lleva cabeceras
Origin y Referer falsificadas que dicen venir de un dominio interno de
documentación de Alibaba.
Un grupo de comandos convierte esto en una historia de agentes de código.
Junto a los verbos habituales, el RAT trae aipoison, aipoison_inject y
aipoison_deploy. Parchean scripts de Python instalados en los directorios
.skills de herramientas de desarrollo concretas, marcando el fragmento
inyectado con # __INJECT_MARKER__, para que un script traído del C2 se
ejecute más tarde, desde dentro de la herramienta, como tú. Entre los
objetivos nombrados está
Qoder,
el IDE agéntico de la propia Alibaba, que superó los cinco millones de
usuarios a los pocos meses de lanzarse el agosto pasado.
Alguien se sentó, miró la máquina del desarrollador moderno y eligió la
carpeta de skills del agente como el punto de apoyo duradero: un directorio
de scripts que se ejecuta con tus permisos al inicio de cada sesión, y que
casi nadie revisa nunca con un diff. Ya vimos este movimiento antes, cuando
un gusano se copió dentro de .claude
para que el siguiente arranque del agente reinfectara la máquina. Se ha
graduado: del truco improvisado de un gusano a un comando con nombre en un
kit de espionaje.
Las partes que el atacante no podía esconder
Leer el código nunca iba a encontrar esto. El ataque aún tenía requisitos, y todos eran visibles: un paquete sin historial y sin reputación, tres conexiones salientes antes de poder actuar (el archivo de reglas en GitHub, la etapa en el almacenamiento en la nube, el C2), y una máquina que seguiría ahí mañana.
Bromure Agentic Coding pone una decisión sobre cada uno de ellos, y la toma en tu Mac, fuera de la caja donde corre el agente, donde nada de dentro puede discutir.
La instalación se detiene en el registro. Cada descarga de paquete
cruza el proxy del lado del host, que aplica la política de supply chain de
tu espacio de trabajo a la respuesta antes de que un byte llegue a la VM.
Activa el filtrado de paquetes y el proxy consulta un proveedor de
reputación por cada artefacto. Uno de los dos proveedores seleccionables es
Socket, cuya investigación es el tema de este artículo. Cuando ninguna
fuente habilitada puede avalar un paquete, el proxy retiene la descarga y
te pregunta. Los dobles de un scope privado, publicados el trimestre pasado
con un puñado de descargas y sin reputación en ninguna parte, se detienen
ahí. La aplicación vive en el host por diseño: el .npmrc dentro de la VM
puede endurecer la política y no puede aflojarla, así que la regla se
mantiene incluso cuando la cosa comprometida es la cosa que
vigila.
El cable rechaza el ensamblaje. Este diseño se rompe contra el
consentimiento de salida, porque sin nada hostil en el tarball, la red es
el ataque. El proxy del host comprueba cada una de las tres descargas (el
archivo raw del GitHub del atacante, el bucket que sirve setting.js, el
host de C2) contra los destinos que aprobaste para este perfil. El registro
desde el que instalas está en esa lista. La ruta raw de un desconocido y un
bucket bautizado con el nombre de un CLI del que nunca has oído hablar no
lo están. El proxy no tiene opinión sobre items.constructor.constructor y
no la necesita. Lee el destino, no encuentra nada aprobado y corta la
conexión. Tu instalación termina, tu build corre, y el RAT nunca se arma,
porque sus piezas nunca llegan a la misma habitación.
La persistencia recibe una máquina con una vida útil de una tarea.
Supón que toda la cadena corre de todos modos, porque aprobaste un destino
más amplio de lo que querías y las etapas aterrizan. La línea en
~/.zshrc, el LaunchAgent de los diez minutos, el app.asar troyanizado,
el Python de .skills parcheado: todo eso se escribe en una VM Linux
desechable, a un hipervisor de macOS, que guarda el espacio de trabajo de
esta tarea, y que tiras cuando el trabajo se fusiona. aipoison es una
apuesta a que la herramienta que parchea y el host que comprometió son la
misma máquina longeva. En un perfil, esa apuesta pierde. El reconocimiento
que corre primero vuelve con señuelos del
broker: tus credenciales reales viven
en el host y se inyectan en el cable solo para destinos aprobados, así que
nunca estuvieron en la VM para
ser recolectadas.
Revisar un artefacto te informa sobre el artefacto
Los investigadores vuelven a enseñar esta lección cada semana en una biblioteca distinta. Ayer, una flag de confianza cayó porque la comprobación y la carga ocurrían en momentos distintos. En junio, un repositorio se mantuvo limpio porque el reverse shell vivía en un registro DNS. Ahora dieciocho paquetes se leen limpios porque la parte maliciosa es un archivo JSON que el atacante todavía sostiene.
Los agentes afilan esto, porque son rápidos. Un agente al que le pides conectar una API interna añade la dependencia, ejecuta la instalación y pasa al siguiente paso de la tarea en lo que tardas en cambiar de ventana. Esa velocidad es la razón entera por la que lo compraste. Pon el juicio donde la velocidad no pueda adelantarlo: en la descarga del registro y en el cable, donde tu Mac decide contra una política que definiste una vez, para cada paquete y cada conexión que hace el agente.
Sigue dejando que el agente instale cosas, porque ahí está la palanca. Instala Bromure Agentic Coding, activa las capas de supply chain y dale al perfil una lista de destinos que tengan sentido para el trabajo. La próxima campaña esconderá su payload en otro sitio, la única predicción segura en este negocio, y aun así tendrá que descargarlo por un cable que te pregunta primero.