- El paquete Lotusbail es un fork de la biblioteca legítima de WhatsApp Web API Baileys y es un paquete con malware que fue descargado más de 56 mil veces en npm durante 6 meses
- Mientras ofrece funciones de API que operan con normalidad, roba credenciales de WhatsApp, mensajes, contactos y archivos multimedia y los envía al servidor del atacante
- Los datos se transmiten tras pasar por múltiples capas de cifrado y ofuscación como RSA, AES, Base-91 y LZString, lo que permite evadir el monitoreo de seguridad
- El paquete instala una puerta trasera que conecta de forma permanente el dispositivo del atacante a la cuenta de WhatsApp del usuario mediante un código de emparejamiento hardcodeado
- Este caso muestra la sofisticación creciente de los ataques a la cadena de suministro y subraya la necesidad de vigilancia de seguridad basada en comportamiento, imposible de detectar solo con análisis estático
Resumen del paquete Lotusbail
lotusbail es un fork del legítimo @whiskeysockets/baileys y ofrece exactamente las funciones de WhatsApp Web API
- El envío y recepción de mensajes funciona normalmente, por lo que es muy probable que los desarrolladores lo instalen sin sospechar
- Ha estado publicado en npm durante 6 meses y, al momento de redactar esto, todavía puede descargarse
- Detrás de su funcionalidad real se esconden acciones maliciosas como robo de credenciales de WhatsApp, interceptación de mensajes, recolección de contactos e instalación de backdoor
Información que roba
- Incluye tokens de autenticación y claves de sesión, historial completo de mensajes, lista de contactos con números de teléfono, archivos multimedia y documentos y acceso persistente mediante backdoor
- Todos los datos se cifran antes de enviarse al servidor del atacante
Cómo funciona
Funcionalidad de fachada que sí opera
- La mayoría de los paquetes npm maliciosos fallan o se identifican fácilmente por código sospechoso, pero Lotusbail se disfraza como una API que funciona normalmente
- Está basado en la biblioteca legítima Baileys y tiene la función de envío y recepción de mensajes completamente implementada
- Por ello se emplea una técnica de ingeniería social que hace que los desarrolladores no sospechen de comportamiento malicioso en un “código que funciona bien”
Robo y transmisión de datos
- El paquete funciona envolviendo al cliente WebSocket que se comunica con WhatsApp
- Durante la autenticación captura credenciales y, al recibir o enviar mensajes, duplica todo el contenido
- La función normal se mantiene intacta; simplemente todos los datos se envían también al atacante
- Los datos robados se transmiten cifrados con una implementación personalizada de RSA
- Existe por separado del cifrado de extremo a extremo de WhatsApp y se usa como cifrado para evadir la vigilancia de red
- La dirección del servidor no aparece expuesta directamente en el código, sino que está oculta dentro de una cadena de configuración cifrada
- Se aplica una ofuscación de 4 etapas con manipulación de variables Unicode, compresión LZString, codificación Base-91 y cifrado AES
Instalación de la puerta trasera
- Abusa de la función de código de emparejamiento de dispositivos de WhatsApp para vincular el dispositivo del atacante con la cuenta del usuario
- El paquete incluye un código de emparejamiento hardcodeado cifrado con AES
- Cuando el usuario se autentica, el dispositivo del atacante también se conecta al mismo tiempo y obtiene acceso persistente a la cuenta
- El atacante puede lograr control total de la cuenta, incluyendo lectura y envío de mensajes, descarga de contenido multimedia y acceso a contactos
- Aunque se elimine el paquete npm, el dispositivo del atacante sigue conectado, y solo puede bloquearse desvinculando manualmente todos los dispositivos desde la configuración de WhatsApp
Técnicas para evadir el análisis
- El código incluye 27 trampas de bucle infinito que detienen la ejecución cuando detectan herramientas de depuración
- Detecta depuradores, argumentos de proceso y entornos sandbox para obstaculizar el análisis dinámico
- Hay comentarios en las secciones de código malicioso y existen rastros de una gestión de desarrollo sistemática
Conclusión e implicaciones de seguridad
- La sofisticación de los ataques a la cadena de suministro sigue avanzando y aumentan los casos disfrazados como código que funciona normalmente
- Es difícil detectarlo solo con análisis estático y verificación basada en reputación, y se necesita análisis de comportamiento en ejecución (behavioral analysis)
- El caso de Lotusbail explota la brecha de seguridad de “creer que un código es seguro porque funciona” y muestra la importancia de construir sistemas de monitoreo del comportamiento en tiempo de ejecución
- El equipo de investigación de Koi Security identificó amenazas que eluden los procedimientos de verificación existentes mediante estas técnicas de detección basadas en runtime
1 comentarios
Opiniones en Hacker News
Cada vez que ocurre un incidente de malware, es frustrante ver que el equipo de seguridad responde bloqueando aún más los datos
La filtración de mensajes de WhatsApp fue el detonante, pero al final habrían robado otra cosa
Si se impide que una app lea datos salvo con firmas específicas, también se vuelven imposibles los respaldos legítimos o el acceso a los datos
Está bien reforzar la seguridad, pero creo que una sobrerreacción defensiva de bloquearlo todo crea otro problema
El usuario accede como si conectara otro cliente a su cuenta de WhatsApp, y como resultado se obtiene acceso a todos los datos
Si WhatsApp hubiera ofrecido una API oficial decente, esto habría pasado menos
Documentación relacionada: Baileys Wiki
Antes había más malware, pero también había más libertad e interoperabilidad
Creo que este tipo de ataque ya es un resultado previsible
Los gestores de paquetes como NPM son intrínsecamente vulnerables porque traen dependencias justo antes del build
El problema es una cultura que esquiva el sistema de control de versiones y acepta montones de dependencias sin validarlas
No solo NPM: Cargo, Docker, CI/CD y todo el ecosistema tienen problemas parecidos
La estructura de “instalar por nombre y ya” implica demasiada confianza
No hay una solución clara: no podemos renunciar a colaborar, pero tampoco es posible una seguridad perfecta
Al final, el monstruo ya está dentro de la casa
Aunque se indicara directamente una URL de git, el resultado sería el mismo
Al final es un problema estructural de la gestión de dependencias
Siento que hace falta un gestor de paquetes estandarizado e independiente del lenguaje
Funciones como verificación de firmas, garantía de procedencia y estandarización de APIs serían esenciales
Como en el caso de xz, también pueden distribuirse paquetes comprometidos tal cual
Además, los gestores del sistema tardan en soportar versiones recientes, así que no son adecuados para desarrollo
Por eso al final se necesitan herramientas como npm, cargo o pip
No es un problema del gestor de paquetes, sino de que el código no era confiable desde el principio
Da risa que el autor del malware haya usado nombres de funciones tan obvios como exfiltrateCredentials
Es irónico que incluso agregara detección de depuradores, pero no ofuscara el código
Ya vivimos en una época en la que probar malware también es una forma de desarrollo
La frase “dependencias que los desarrolladores instalan sin pensar” da escalofríos
Salvo en organizaciones con políticas de seguridad estrictas, es difícil impedirlo en la práctica
Quizá la única solución sea usar menos npm
Si se especifican por tag, en cualquier momento quedas expuesto a un ataque a la cadena de suministro
La industria funciona sobre mucha más confianza ciega de la que parece
Los sistemas de despliegue automático ni siquiera tienen margen para “pensarlo dos veces”
Ojalá JavaScript tuviera una biblioteca grande y confiable como Apache Commons
Introducción a Apache Commons
El paquete lotusbail es un paquete malicioso de npm que se hacía pasar por la API de WhatsApp Web
Se distribuyó durante 6 meses y realizó varios ataques, como robo de credenciales, intercepción de mensajes e instalación de puertas traseras
Los desarrolladores que dependen del ecosistema JS necesitan de forma realista una estrategia de mitigación de riesgos
Se mencionan métodos como usar Docker o máquinas virtuales
Contenerizamos todos los entornos de desarrollo y fijamos las dependencias a versiones bloqueadas
Prohibimos instalaciones globales, desactivamos actualizaciones automáticas y exigimos validación manual
En proyectos sensibles, reinicializábamos periódicamente estaciones de trabajo dedicadas
Es molesto, pero esa es la seguridad realista
O también puedes irte del ecosistema JS
Debería ser posible confirmar a nivel del SO o de Docker si se permite o no la conexión de red
Comparte el kernel, pero basta para frenar ataques del ecosistema JS
Si algún día aparece en npm un ataque de escape de contenedor, entonces me pasaré a una VM
Al principio pensé que era seguridad excesiva, pero ahora veo que también es rápido y estable
Porque para entonces ya suele saberse si son maliciosos o no
Este paquete fue una falla de seguridad desde el principio
Usaba una reimplementación de autenticación del cliente en vez de una API oficial, y secretos del usuario eran procesados por un tercero
El usuario también debió tener más cuidado, pero no es fácil culparlo por completo
Solo se puede acceder a la API registrándose en la WhatsApp Business Platform
Si hubiera existido una API real, esto no habría pasado
Lo peligroso es entregar secretos al tercero durante la autenticación
Normalmente este tipo de paquetes se instala para automatizar la propia cuenta
Últimamente hay demasiados posts de blog generados por LLM
La calidad es baja, pero como el costo es 0, desde el punto de vista del marketing resulta eficiente
La escritura tradicional ya se volvió algo legacy
Parece que están aumentando los ataques a la cadena de suministro. ¿Cómo deberían responder los desarrolladores?
Hay que detectar estos patrones con escaneo automático y reforzar los procesos de verificación
Contenerización, bloqueo de dependencias, escaneo de seguridad y actualizaciones diferidas son imprescindibles
La instalación global de npm es la peor opción
Hay que usar contenedores o VMs como rootless podman para minimizar el riesgo