LiteLLM reveló el pasado viernes que una clave maestra de la plataforma Agent Platform fue publicada accidentalmente en un repositorio público de GitHub a finales de mayo de 2026, lo que permitió a un atacante llevar a cabo la inyección de una versión maliciosa de un popular paquete de Python. Según explicaron Oliver Jensen y Mateo Wang de LiteLLM, el 27 de mayo de 2026 se comprometió un archivo de configuración en el repositorio público LiteLLM-Labs/lite-harness, el cual contenía inadvertidamente la clave maestra de una implementación de la plataforma Agent Platform, una herramienta de código abierto utilizada para orquestar agentes.
El error fue rápidamente identificado, y se realizó un "force push" para eliminar el commit, reconociendo que las claves expuestas requerían ser revocadas. Sin embargo, la revocación de la clave maestra no se llevó a cabo. Este lapsus permitió que un atacante no identificado, que operaba desde la dirección IP "69.48.229[.]143", utilizara la clave no revocada el 10 de octubre de 2026. Con esta clave, el atacante pudo acceder a la plataforma Agent y extraer un token OAuth de GitHub CLI que el servicio tenía configurado para permitir que agentes en la nube autoalojados pudieran realizar solicitudes de extracción a los repositorios de GitHub.
De acuerdo con los desarrolladores de este modelo de lenguaje de código abierto, el token no estaba limitado a un ámbito específico y estaba asociado a la cuenta del propietario de la organización en GitHub. El acceso al token otorgó al atacante privilegios a nivel de propietario en todos los repositorios de la organización, lo que le permitió llevar a cabo una exfiltración adicional de credenciales. Las acciones sucesivas realizadas por el actor de amenazas tras este acceso se desarrollaron de la siguiente manera:
El 10 de octubre de 2026, entre las 22:11 y las 22:12 UTC, el autor realizó commits en ramas efímeras de repositorios internos para ejecutar flujos de trabajo (BerriAI/litellm y BerriAI/litellm-auto) diseñados para adquirir tokens OAuth de GitHub CLI asociados a dos ingenieros con privilegios de mantenimiento a través de un endpoint de webhook controlado por el atacante. Ambas ejecuciones fueron eliminadas minutos después. Posteriormente, el 21 de octubre de 2026, entre las 10:08 y las 11:08 UTC, se sobrepasaron las protecciones de ramas y se alteró el pipeline de lanzamiento, apuntando la fuente al repositorio similar "Berri-AI/litellm" en lugar de "BerriAI/litellm".
A las 11:39 y 11:40 UTC del mismo día, se publicó la versión 1.107.0 de LiteLLM en PyPI, y a las 11:46 UTC se publicaron imágenes en Docker Hub y GHCR. Más tarde, entre las 11:53 y las 11:54 UTC, los registros de ejecución de producción y staging fueron eliminados, y a las 12:06 UTC, un investigador de Upwind, Lidor Machluf, reportó el ataque a la cadena de suministro. Finalmente, a las 13:23 UTC, PyPI puso en cuarentena la versión 1.107.0 de LiteLLM, y a las 14:20 UTC, las etiquetas de Docker Hub v1.107.0, latest, main-latest y main-stable fueron eliminadas o redirigidas a imágenes verificadas y limpias.
LiteLLM explicó que, en condiciones normales, la creación y publicación de un lanzamiento requiere la autorización de un ingeniero autorizado y la aprobación de una cuenta especial bloqueada a un dispositivo físico en sus oficinas. Sin embargo, esta restricción fue relajada a principios de esa semana para facilitar un lanzamiento más frecuente de correcciones de errores, permitiendo que cualquier par de ingenieros pudieran desencadenar y aprobar un lanzamiento. Esto permitió al atacante utilizar uno de los tokens para iniciar el lanzamiento (tras haber redirigido al desplegador hacia su repositorio malicioso) y otro para aprobarlo.
Además, los mantenedores del proyecto señalaron que el atacante podría haber relajado aún más esta restricción o eliminarla por completo, dado que ya poseía un token perteneciente a un propietario de la organización. Se sospecha que esta acción no se tomó para evitar la detección. LiteLLM también indicó que los flujos de trabajo están diseñados para identificar y exfiltrar claves y tokens adicionales, centrándose específicamente en los tokens de API de inferencia ascendentes. En respuesta a este incidente, la empresa afirmó que está trabajando para revocar cada uno de los tokens asociados a todos los sistemas internos y plataformas de proveedores.
Socket, que publicó su propia investigación sobre los flujos de trabajo maliciosos, recuperó dos commits maliciosos que añadieron cada uno un flujo de trabajo en ".github/workflows/cache.yml". El primer commit se realizó el 10 de octubre de 2026 a las 22:11:45 UTC, seguido por un segundo commit el 12 de octubre. "Ninguno de los commits fue enviado a una rama que todavía exista", comentó Karlo Zanki, investigador de seguridad de Socket, en un informe compartido con The Hacker News. "Ambos fueron enviados a ramas de corta duración nombradas ci-tmp- que fueron creadas, utilizadas y eliminadas en minutos, razón por la cual la actividad deja casi nada en la historia ordinaria del repositorio".
De acuerdo con el análisis de la firma de seguridad de aplicaciones sobre los registros de actividad del repositorio, ambos commits se basan en un commit legítimo como base de la rama para hacer que el push parezca inofensivo. Se crea una rama desechable llamada "ci-tmp-" (específicamente, ci-tmp-a351cc y ci-tmp-4d8517) a partir de un commit legítimo reciente en el repositorio y se empuja un commit que añade ".github/workflows/cache.yml" con el mismo asunto, "ci: bump cache config". Este flujo de trabajo está configurado para ejecutarse cada vez que se envía un commit o etiqueta, lo que provoca que se active.
Ambos flujos de trabajo, tal como lo destacó LiteLLM, están equipados para recoger tokens de GitHub y claves API para el espacio de trabajo Linear de la organización, la implementación de LiteLLM y Together AI, así como el identificador y la clave de firma de una aplicación de GitHub. La ejecución del 12 de octubre amplía la recolección a más secretos, incluidos las claves API de Anthropic, OpenAI, AWS Bedrock, Tavily y el inquilino de escaneo de secretos de GitGuardian. También captura el estado de almacenamiento de Playwright, información de bases de datos PostgreSQL (cadena de conexión, nombre de cuenta, contraseña), dirección de endpoint de Redis, puerto y contraseña de autenticación.
Los datos recopilados a partir de ambos flujos de trabajo son exfiltrados a dos diferentes endpoints de webhook[.]site:
- webhook[.]site/65a42464-3cfa-4b02-a18c-17a6d7b86f37 - webhook[.]site/4da03473-a3e7-4dc2-a087-9c564b4208e1
Un token de GitHub y una clave privada de aplicación de GitHub son credenciales específicas para la plataforma que alberga el repositorio, y no para un servicio de terceros, afirmó Zanki. Por otra parte, el identificador GITGUARDIAN_API_KEY se refiere a una credencial de la propia plataforma de escaneo de secretos, lo que otorga a un atacante visibilidad y, potencialmente, control sobre las alertas generadas por esta actividad.
El parámetro E2E_LINEAR_STORAGE_STATE_B64 representa el estado de la sesión del navegador serializado, utilizado por Playwright para realizar pruebas de extremo a extremo. Un estado de almacenamiento válido permite acceso autenticado a la cuenta asociada de Linear sin necesidad de contraseña y eludiendo los requerimientos de autenticación multifactor.
Los hallazgos descartan la hipótesis inicial de LiteLLM, que sostenía que los tokens OAuth de la interfaz de línea de comandos de GitHub fueron sustraídos de los registros de una implementación interna de LiteLLM. "La investigación fue un proceso en el que continuamente aprendimos información adicional, lo que significó que algunas de nuestras suposiciones y creencias resultaron ser inexactas o incompletas", reconoció Jensen.
Múltiples informes han revelado que los archivos incluidos en la versión 1.107.0 de LiteLLM están diseñados para ejecutarse automáticamente al iniciar Python, incluso si una aplicación no había importado explícitamente LiteLLM.
El malware presenta dos rutas de ejecución: un módulo destinado a la recolección de credenciales que apunta a material de autenticación a través de herramientas de desarrollo, aplicaciones de inteligencia artificial, entornos en la nube y navegadores web; y un backdoor orientado a Unix que se ejecuta como un proceso en segundo plano para descargar y ejecutar código arbitrario proporcionado por el atacante cada hora.
Además, el ladrón de datos recopila información del sistema, archivos SSH, credenciales y tokens de Git y GitLab, variables de entorno, así como tokens asociados a npm, PyPI, pip, Yarn, Maven, Gradle, Composer, RubyGems y Cargo. Esta información es luego comprimida y enviada a "litellm[.]dev/healthcheck" mediante una solicitud HTTP POST. Cabe destacar que el dominio fue registrado el 13 de octubre de 2026, lo que puede implicar un uso malicioso a largo plazo.
"Juntos, estos mecanismos ampliaron la posible exposición más allá de las implementaciones activas de LiteLLM: simplemente iniciar Python en un entorno afectado podría activar el código malicioso, incluso cuando LiteLLM en sí nunca había sido importado", indicó el equipo de Microsoft Security Research.
"Debido a que los archivos de inicio se encontraban fuera del directorio de la aplicación LiteLLM, eliminar únicamente los archivos de la aplicación podría dejar atrás los componentes maliciosos de inicio", concluyeron los investigadores. Este aspecto resalta la importancia de una gestión adecuada de las dependencias y la implementación de medidas de seguridad robustas para mitigar el riesgo de infecciones por malware.
