Tu Pasarela de IA fue una Puerta Trasera: Dentro del Compromiso en la Cadena de Suministro de LiteLLM
Detection stack
- AIDR
- Alert
- ETL
- Query
Resumen
Un compromiso de la cadena de suministro afectó el paquete de Python ampliamente utilizado LiteLLM en PyPI. Las versiones maliciosas 1.82.7 y 1.82.8 entregaron una carga útil de tres etapas diseñada para robar credenciales de la nube, claves SSH, y secretos de Kubernetes, luego moverse dentro de los clústeres y establecer una puerta trasera persistente. La actividad se atribuye al grupo criminal TeamPCP y parece estar conectada a compromisos anteriores que involucraron herramientas de seguridad, incluidas Trivy y Checkmarx.
Investigación
Los investigadores vincularon la cadena de intrusión a una Acción de GitHub de Trivy comprometida que expuso un token de acceso personal, permitiendo un empujón forzado de versiones contaminadas de LiteLLM a PyPI. La revisión del código descubrió un cargador de Python con múltiples capas, con gran uso de Base64, que utilizó RSA-4096 y AES-256 para el despliegue y exfiltración protegidos hacia dominios controlados por el atacante. La carga útil también creó pods de Kubernetes para acceder al sistema de archivos del host y expandir la colección. La reutilización de infraestructura entre PyPI, npm, Docker Hub, GitHub Actions, y OpenVSX indicó una campaña coordinada, multi-ecosistema, en lugar de un secuestro de paquete aislado.
Mitigación
Bloquea los dominios maliciosos identificados, rota cualquier credencial potencialmente expuesta y elimina los artefactos LiteLLM_init.pth. Busca persistencia a través de la unidad de usuario systemd sysmon.service e investiga la creación inesperada de archivos .pth. Reduce la exposición de la cadena de suministro aplicando instalaciones verificadas por hash, limitando o prohibiendo comportamientos post-instalación no revisados y aplicando filtros de salida. Cuando sea posible, añade monitoreo de huellas dactilares JARM para marcar el tráfico asociado con ASN de alojamiento a prueba de balas conocidos.
Respuesta
Si se sospecha de un compromiso, aísla los sistemas afectados, termina los procesos maliciosos de Python y elimina los paquetes trojanizados de LiteLLM junto a cualquier archivo de persistencia. Rota inmediatamente todos los secretos colectados, priorizando credenciales de la nube y LLM claves API. Despliega detecciones para cadenas de ejecución de Python codificadas en Base64, caídas de archivos .pth, y actividad anómala de HTTPS POST a models.litellm.cloud o checkmarx.zone.
Palabras clave: LiteLLM, ataque de cadena de suministro, PyPI, TeamPCP, Trivy, Checkmarx, GitHub Actions, secretos de Kubernetes, persistencia .pth, robo de credenciales, RSA-4096, AES-256, filtrado de salida, huellas JARM.
"graph TB %% Section de Definiciones de Clases classDef action fill:#99ccff classDef technique fill:#ffcc99 classDef tool fill:#cccccc classDef file fill:#e6e6e6 classDef process fill:#ffd966 classDef service fill:#c0c0c0 %% Section de Definiciones de Nodos action_initial_supply_chain["<b>Acción</b> – <b>T1195.001 Comprometer Dependencias de Software y Herramientas de Desarrollo</b><br/>El adversario obtuvo un token de bot de Aqua Security a través de un flujo de trabajo comprometido de Acción de GitHub de Trivy"] class action_initial_supply_chain action tool_trivy_github_action["<b>Herramienta</b> – <b>Nombre</b>: Acción de GitHub de Trivy<br/><b>Descripción</b>: Flujo de trabajo de CI escaneando imágenes de contenedor"] class tool_trivy_github_action tool process_publish_malicious["<b>Proceso</b> – Publicar versiones maliciosas de LiteLLM en PyPI"] class process_publish_malicious process technique_supply_chain_attack["<b>Técnica</b> – <b>T1195.002 Comprometer Cadena de Suministro de Software</b><br/>Versiones maliciosas de LiteLLM 1.82.7 y 1.82.8 empujadas a PyPI"] class technique_supply_chain_attack technique technique_python_execution["<b>Técnica</b> – <b>T1059.006 Intérprete de Comando y Script: Python</b><br/>Archivo .pth cargado automáticamente al inicio del intérprete"] class technique_python_execution technique file_pth["<b>Archivo</b> – LiteLLM_init.pth<br/>Colocado en sitex2011packages, autox2011cargado por el intérprete de Python"] class file_pth file technique_user_execution["<b>Técnica</b> – <b>T1204.002 Ejecución de Usuario: Archivo Malicioso</b><br/>`pip install LiteLLM==1.82.8` dispara ejecución inmediata de carga útil"] class technique_user_execution technique technique_credential_harvest["<b>Técnica</b> – <b>T1552.001 Credenciales en Archivos</b><br/>El recolector lee claves SSH, configuraciones de la nube, archivos .env, credenciales de base de datos, carteras de criptomonedas"] class technique_credential_harvest technique technique_metadata["<b>Técnica</b> – <b>T1552.005 Credenciales No Seguras: API de Metadatos de Instancia de Nube</b><br/>Consulta los servicios de metadatos de AWS, GCP y Azure para tokens IAM temporales"] class technique_metadata technique technique_os_cred_dump["<b>Técnica</b> – <b>T1003 Vertido de Credenciales del SO</b><br/>Lee /etc/shadow y registros de autenticación para datos de credenciales"] class technique_os_cred_dump technique technique_obfuscation["<b>Técnica</b> – <b>T1027 Archivos u Información Ofuscados</b><br/>Múltiples capas de base64, relleno binario, cargas útiles despojadas, resolución dinámica de API, cifrado AESu2011256u2011CBC, wrapper RSAu20114096"] class technique_obfuscation technique technique_exfiltration["<b>Técnica</b> – <b>T1041 Exfiltración a través de Canal C2</b><br/>Paquetes de credenciales cifrados enviados via HTTPS POST a models.litellm.cloud"] class technique_exfiltration technique technique_web_service["<b>Técnica</b> – <b>T1102.001 Servicio Web: Resolver Puerta Trasera</b><br/>La puerta trasera consulta checkmarx.zone/raw para cargas útiles de segunda etapa e informa el estado"] class technique_web_service technique technique_persistence["<b>Técnica</b> – <b>T1543.002 Crear o Modificar Proceso del Sistema: Servicio de Systemd</b><br/>Servicio sysmon de nivel de usuario instalado para persistencia a través de reinicios"] class technique_persistence technique technique_container_lateral["<b>Técnica</b> – <b>T1543.005 Crear o Modificar Proceso del Sistema: Servicio de Contenedor</b><br/>Pods de Kubernetes privilegiados creados con acceso al sistema de archivos del host para movimiento lateral a nivel de clúster"] class technique_container_lateral technique technique_remote_services["<b>Técnica</b> – <b>T1133 Servicios Remotos Externos</b><br/>La puerta trasera persistente permite la ejecución de comandos remotos a través de encuestador C2"] class technique_remote_services technique technique_defense_evasion["<b>Técnica</b> – <b>T1140 Deofuscar/Decodificar Archivos o Información</b><br/>Decodificación en tiempo de ejecución de carga útil de múltiples capas evita la detección estática"] class technique_defense_evasion technique %% Sección de Conexiones action_initial_supply_chain –>|usa| tool_trivy_github_action tool_trivy_github_action –>|lleva a| process_publish_malicious process_publish_malicious –>|resulta en| technique_supply_chain_attack technique_supply_chain_attack –>|habilita| technique_python_execution technique_python_execution –>|carga| file_pth file_pth –>|dispara| technique_user_execution technique_user_execution –>|causa| technique_credential_harvest technique_credential_harvest –>|también realiza| technique_metadata technique_metadata –>|combinado con| technique_os_cred_dump technique_os_cred_dump –>|ofuscado por| technique_obfuscation technique_obfuscation –>|conduce a| technique_exfiltration technique_exfiltration –>|usa| technique_web_service technique_web_service –>|establece| technique_persistence technique_persistence –>|habilita| technique_container_lateral technique_container_lateral –>|soporta| technique_remote_services technique_remote_services –>|facilita| technique_defense_evasion "
Flujo de Ataque
Detecciones
Probable Cifrado o Descifrado de Archivos con OpenSSL [Linux] (a través de cmdline)
Ver
El Archivo Fue Creado en la Carpeta Tmp de Linux (a través de file_event)
Ver
Uso Sospechoso de CURL (a través de cmdline)
Ver
El Archivo Se Creó en la Carpeta Temporal de MacOS (a través de file_event)
Ver
Probable Cifrado o Descifrado de Archivos con OpenSSL [MacOS] (a través de cmdline)
Ver
Posible Archivo de Gancho de Configuración Específica del Sitio Creado (a través de file_event)
Ver
Paquetes de Python maliciosos IOCs (a través de cmdline)
Ver
Intento de Ejecución Sospechosa de Curl [MacOS] (a través de cmdline)
Ver
Creación de Archivo de Servicio en la Carpeta de Systemd (a través de file_event)
Ver
IOCs (DestinationIP) para detectar: Tu Puerta de Enlace de IA era una Puerta Trasera: Dentro del Compromiso de la Cadena de Suministro de LiteLLM
Ver
IOCs (SourceIP) para detectar: Tu Puerta de Enlace de IA era una Puerta Trasera: Dentro del Compromiso de la Cadena de Suministro de LiteLLM
Ver
Paquete LiteLLM Malicioso Detectado vía Archivo .pth y Uso de subprocess.Popen [Creación de Proceso en Linux]
Ver
Exfiltración y Comunicación C2 a través de Dominios Maliciosos en Ataque de la Cadena de Suministro de LiteLLM [Firewall]
Ver
Ejecución de Simulación
Requisito previo: El Chequeo Previo de Telemetría y Línea Base debe haber pasado.
Razonamiento: Esta sección detalla la ejecución precisa de la técnica del adversario (TTP) diseñada para disparar la regla de detección. Los comandos y la narrativa DEBEN reflejar directamente los TTPs identificados y apuntar a generar la telemetría exacta esperada por la lógica de detección. Los ejemplos abstractos o no relacionados llevarán a un diagnóstico incorrecto.
-
Narrativa del Ataque y Comandos:
Un atacante que ha comprometido el públicoLiteLLMEl paquete PyPI inyecta un.ptharchivo malicioso llamadoLiteLLM_init.pth. El archivo se coloca en el directorio de paquetes completados globales, asegurando que se procese cada vez que any el intérprete de Python se inicia. El.pthcontiene una sola línea que ejecuta una carga útil codificada en base64 a través desubprocess.Popen. La carga útil descarga una herramienta de segunda etapa de un servidor C2 sobre HTTPS (T1071.001) y escribe credenciales robadas en/tmp/creds.txt(T1552.*). Al usar el gancho de inicio del intérprete, el atacante logra persistencia sin modificar las unidades de systemd, evadiendo muchas bases de creación de procesos tradicionales.Los pasos simulados son:
- Crear el
.ptharchivo malicioso con código Python embebido. - Desencadenar el inicio del intérprete de Python (por ejemplo,
python3 -c "import sys"), causando que el.pthse ejecute. - El código incrustado decodifica la carga útil base64 y la lanza con
subprocess.Popen, generando un proceso cuya línea de comando contiene tantoLiteLLM_init.pth(desde la ruta de importación del intérprete) comosubprocess.Popen.
- Crear el
-
Script de Prueba de Regresión:
El siguiente script automatiza toda la simulación de ataque en el host de prueba Ubuntu.#!/usr/bin/env bash set -euo pipefail # ---------- 1. Construir carga útil maliciosa .pth ---------- MALICIOUS_PTH_PATH="/usr/local/lib/python3.8/dist-packages/LiteLLM_init.pth" PAYLOAD_B64="aW1wb3J0IHN1YnByb2Nlc3MsIGJhc2U2NApzb3VyY2U9J2h0dHBzOi8vZXhhbXBsZS5jb20vc2Vjb25kX3N0YWdlLnB5JwoKc3VicHJvY2Vzcy5Qb3BlbihuYW1lPXNvdXJjZSwgc2hlbGxfcGF0aD0iL2Jpbj9jaG93IiwgY2xhc3M9ZnVuY3Rpb24oKSB7fSlzc2V0ZXJ0JkNsb3JlZChzc2V0KX0p" # Lo anterior decodifica a un pequeño script python que descargaría una carga útil de segunda etapa. # Para seguridad en un entorno de prueba lo reemplazamos con un comando de eco inofensivo. PAYLOAD_B64=$(echo -n "import subprocess,base64; subprocess.Popen(['bash','-c','echo malicious executed >> /tmp/malicious.log'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)" | base64 -w0) # Escribe el archivo .pth – la línea es ejecutada como código Python durante el inicio del intérprete echo "exec('import base64, subprocess; subprocess.Popen(base64.b64decode("${PAYLOAD_B64}"), shell=True)')" | sudo tee "${MALICIOUS_PTH_PATH}" >/dev/null echo "[+] Archivo .pth malicioso creado en ${MALICIOUS_PTH_PATH}" # ---------- 2. Disparar el inicio del intérprete (genera telemetría) ---------- echo "[+] Disparando el intérprete de Python para cargar .pth..." python3 -c "import sys; print('trigger')" # ---------- 3. Verificar que la carga útil se ejecutó correctamente ---------- if grep -q "malicious executed" /tmp/malicious.log; then echo "[+] La carga útil se ejecutó con éxito – la detección debería activarse." else echo "[-] La carga útil NO se ejecutó – verifica la colocación y permisos del .pth." fi -
Comandos de Limpieza:
#!/usr/bin/env bash set -euo pipefail MALICIOUS_PTH_PATH="/usr/local/lib/python3.8/dist-packages/LiteLLM_init.pth" # Elimina el archivo .pth malicioso if sudo test -f "${MALICIOUS_PTH_PATH}"; then sudo rm -f "${MALICIOUS_PTH_PATH}" echo "[+] Archivo .pth malicioso eliminado." fi # Elimina el archivo de evidencia creado por la carga útil if test -f "/tmp/malicious.log"; then sudo rm -f "/tmp/malicious.log" echo "[+] Limpiado /tmp/malicious.log." fi # Opcionalmente elimina la regla de auditoría (si añadiste una regla de prueba dedicada) # sudo auditctl -d always,exit -F arch=b64 -S execve -k process_creation