TeamPCP compromete versões do LiteLLM em ataque à cadeia de suprimentos via CI/CD

TeamPCP compromete versões do LiteLLM em ataque à cadeia de suprimentos via CI/CD

Versões 1.82.7 e 1.82.8 do pacote Python litellm foram publicadas com coleta de credenciais, movimentação em Kubernetes e persistência por serviço systemd.

ComponentePacote Python litellm nas versões 1.82.7 e 1.82.8 publicadas no PyPI, com alterações maliciosas no artefato distribuído.
VetorComprometimento provavelmente associado ao uso do Trivy no fluxo de CI/CD do projeto, com injeção durante ou após a geração do wheel.
ImpactoColeta de chaves SSH, credenciais de nuvem, segredos Kubernetes, carteiras de criptomoedas e arquivos .env, seguida de exfiltração e instalação de backdoor persistente.
PrioridadeLocalizar ambientes que instalaram litellm 1.82.7 ou 1.82.8, isolar sistemas afetados, remover artefatos suspeitos e rotacionar credenciais expostas ao ambiente.
ArtefatosCódigo malicioso em litellm/proxy/proxy_server.py na versão 1.82.7 e inicialização automática por litellm_init.pth na versão 1.82.8.
IoCsDomínios defangados models.litellm[.]cloud, checkmarx[.]zone e referência de controle youtube[.]com; arquivo de exfiltração tpcp.tar.gz; serviço sysmon.service.
MitigaçãoReverter para versão limpa, auditar egress HTTPS, revisar pipelines que usaram Trivy ou KICS em janelas de comprometimento e validar identidades não humanas.
Resumo técnico

O grupo TeamPCP ampliou uma campanha de cadeia de suprimentos ao comprometer o pacote Python litellm, usado em ambientes que integram aplicações e serviços relacionados a modelos de linguagem. As versões 1.82.7 e 1.82.8 foram publicadas em 24 de março de 2026 com comportamento malicioso embutido e posteriormente removidas do PyPI. O incidente não se limita a um pacote isolado: o mesmo ator já havia sido associado a comprometimentos envolvendo Trivy e KICS, e o novo caso indica uma progressão de credenciais obtidas em ambientes de desenvolvimento para artefatos consumidos em produção.

A carga implantada nas versões afetadas combina três funções principais. A primeira coleta credenciais e arquivos sensíveis acessíveis ao processo Python, incluindo chaves SSH, credenciais de provedores de nuvem, segredos Kubernetes, carteiras de criptomoedas e arquivos .env. A segunda tenta usar tokens de conta de serviço Kubernetes quando disponíveis para enumerar nós e distribuir pods privilegiados. A terceira instala persistência por systemd, usando o serviço sysmon.service e um script em ~/.config/sysmon/sysmon.py, que consulta periodicamente infraestrutura externa para obter estágios adicionais.

A diferença entre as duas versões afetadas altera a superfície de execução. Na 1.82.7, o código malicioso foi incorporado ao arquivo litellm/proxy/proxy_server.py e é acionado quando litellm.proxy.proxy_server é importado. Na 1.82.8, o vetor foi expandido com um arquivo litellm_init.pth no diretório raiz do wheel. Arquivos .pth colocados em site-packages são processados automaticamente pelo mecanismo de inicialização do Python, o que permite executar lógica no início de qualquer processo Python dentro daquele ambiente, mesmo quando a aplicação não importa explicitamente o módulo do LiteLLM.

Fluxo técnico

O fluxo começa no artefato de distribuição do pacote. A versão 1.82.7 contém uma injeção no caminho litellm/proxy/proxy_server.py, aparentemente aplicada durante ou depois da construção do wheel. Essa posição no pacote é relevante porque o proxy do LiteLLM tende a ser carregado em ambientes nos quais o software atua como camada de intermediação entre aplicações, chaves de API e provedores de modelos. Quando o módulo é importado, a carga é executada sem exigir interação adicional do usuário, reduzindo a dependência de chamadas explícitas a funções suspeitas.

A versão 1.82.8 introduz um acionador mais abrangente. O arquivo litellm_init.pth executa uma linha de inicialização que lança um processo Python separado por meio de subprocess.Popen, permitindo que a rotina maliciosa continue em segundo plano. O conteúdo decodifica uma carga embutida e inicia um orquestrador responsável por desempacotar o coletor de credenciais e o instalador de persistência. O uso de processo filho também dificulta a associação direta entre a aplicação original e os eventos posteriores, especialmente quando a telemetria de endpoint não correlaciona criação de processo, ambiente Python e pacote instalado.

A etapa de coleta busca material sensível em locais normalmente acessíveis a aplicações de backend, agentes de CI/CD e workloads cloud-native. O pacote procura chaves SSH, credenciais de nuvem, segredos do Kubernetes, carteiras de criptomoedas e arquivos de configuração como .env. Os dados coletados são agrupados em um arquivo chamado tpcp.tar.gz e enviados por uma requisição HTTPS POST para o domínio defangado models.litellm[.]cloud. Como a exfiltração usa saída HTTPS, a detecção depende de inspeção de destino, reputação, padrões de egress e correlação com a instalação do pacote afetado.

Em ambientes Kubernetes, a carga tenta aproveitar o token de conta de serviço disponível no pod ou no contexto da aplicação. Se o token permitir enumeração do cluster, o código lista nós e cria pods privilegiados em cada um deles. Esses pods usam acesso ao sistema de arquivos do host por meio de chroot para instalar o dropper de persistência em cada nó. O serviço resultante, sysmon.service, aponta para ~/.config/sysmon/sysmon.py, mesmo nome observado em comprometimento anterior envolvendo Trivy. O script consulta checkmarx[.]zone/raw a cada 50 minutos para recuperar uma URL de próximo estágio; caso a URL contenha youtube[.]com, a execução é interrompida, funcionando como padrão de kill switch observado nos incidentes relacionados.

Superfície afetada

A exposição direta atinge ambientes que instalaram e executaram litellm 1.82.7 ou 1.82.8. A presença do pacote no cache local, em imagens de contêiner, em ambientes virtuais Python, em camadas de build ou em runners de CI/CD deve ser tratada como evidência para análise, mas o risco maior está nos sistemas onde o pacote foi importado ou onde a versão 1.82.8 foi carregada pelo mecanismo .pth durante a inicialização do interpretador. Em instalações com a versão 1.82.8, o simples início de processos Python no ambiente pode ter sido suficiente para acionar a carga.

O impacto é mais severo quando o pacote roda em ambientes com segredos de alto privilégio. Isso inclui pods com contas de serviço Kubernetes permissivas, máquinas de build com tokens de publicação, runners com credenciais de nuvem, servidores de proxy com chaves de provedores de IA e workloads que armazenam segredos em variáveis de ambiente ou arquivos de configuração. A presença do LiteLLM em ambientes cloud-native e de IA amplia a relevância do incidente porque esses sistemas frequentemente concentram chaves de API, tokens de infraestrutura e permissões automatizadas para integração entre serviços.

O caso também mostra uma cascata entre ecossistemas. O comprometimento foi associado a uma dependência de varredura de segurança no fluxo de CI/CD, com encadeamento a partir de incidentes anteriores envolvendo Trivy e KICS. A campanha já tocou GitHub Actions, Docker Hub, npm, Open VSX e PyPI, indicando foco em pontos de alta alavancagem da cadeia de desenvolvimento. Há ainda alegação de colaboração com o grupo de extorsão LAPSUS$, mas essa informação deve ser tratada como limite de atribuição e não como confirmação técnica de participação operacional em cada etapa.

  • Ambientes Python com litellm 1.82.7 ou 1.82.8 instalado, inclusive imagens de contêiner e ambientes virtuais persistidos.
  • Clusters Kubernetes nos quais o processo afetado tinha token de conta de serviço com permissão para enumerar nós e criar pods privilegiados.
  • Runners de CI/CD, servidores de build e workloads com credenciais em variáveis de ambiente, arquivos .env, configurações locais ou diretórios de usuário.
  • Pipelines que usaram Trivy ou KICS durante janelas de comprometimento relacionadas à campanha TeamPCP.
Hunting e telemetria

A investigação deve começar pelo inventário de pacotes. Registros de instalação, manifests de dependências, lockfiles, caches de gerenciadores Python, SBOMs, camadas de imagem e logs de build devem ser consultados para identificar litellm 1.82.7 ou 1.82.8. Em seguida, a análise precisa separar mera presença do pacote de execução provável: importações de litellm.proxy.proxy_server, inicialização de processos Python em ambientes com o .pth malicioso e eventos de criação de processo filho associados ao interpretador são sinais de maior prioridade.

Na rede, a busca deve focar egress HTTPS para models.litellm[.]cloud e consultas ou conexões envolvendo checkmarx[.]zone. O domínio youtube[.]com aparece como condição de interrupção do estágio posterior, não como infraestrutura de comando confirmada para exfiltração. A telemetria de proxy, DNS, EDR e firewall deve ser correlacionada com a linha do tempo de instalação do pacote, criação do arquivo tpcp.tar.gz, execução de Python em segundo plano e qualquer tentativa de comunicação periódica em intervalo próximo de 50 minutos.

Em Kubernetes, a investigação precisa procurar criação inesperada de pods privilegiados, uso de hostPath ou montagem equivalente do sistema de arquivos do host, chamadas de API para enumeração de nós e eventos vindos de contas de serviço associadas ao workload que executava LiteLLM. Nos nós, a presença de sysmon.service e do arquivo ~/.config/sysmon/sysmon.py deve ser tratada como evidência de persistência. A revisão deve incluir tanto o namespace da aplicação quanto nós que não executavam originalmente o serviço, pois a carga tenta se propagar para cada nó acessível.

  • Instalação de litellm 1.82.7 ou 1.82.8 em logs de build, ambientes virtuais, imagens e caches de dependências.
  • Arquivo litellm_init.pth no site-packages e alterações inesperadas em litellm/proxy/proxy_server.py.
  • Criação ou execução de tpcp.tar.gz, sysmon.service ou ~/.config/sysmon/sysmon.py em hosts e contêineres.
  • Egress HTTPS para models.litellm[.]cloud e consultas recorrentes a checkmarx[.]zone.
  • Pods privilegiados inesperados, enumeração de nós Kubernetes e uso anômalo de tokens de conta de serviço.
Mitigação

A primeira medida é impedir nova execução. Sistemas com litellm 1.82.7 ou 1.82.8 devem ser isolados para análise, e o pacote deve ser revertido para uma versão limpa somente depois de preservar evidências relevantes. Em ambientes de contêiner, a substituição da imagem deve ocorrer junto com a invalidação de caches de build e reexecução controlada do pipeline a partir de dependências verificadas. Remover apenas o pacote em um host já executado não é suficiente quando há possibilidade de persistência por systemd ou movimentação para nós Kubernetes.

Credenciais acessíveis ao ambiente afetado devem ser consideradas expostas. Isso inclui variáveis de ambiente, arquivos .env, chaves SSH, tokens de nuvem, segredos Kubernetes, credenciais de publicação, chaves de provedores de IA e identidades não humanas usadas por CI/CD. A rotação deve seguir criticidade e alcance: primeiro credenciais com privilégio de escrita, publicação, administração de cluster, acesso a repositórios e controle de infraestrutura; depois segredos de aplicação e chaves de integração. A revogação deve ser acompanhada de verificação de uso posterior à janela de comprometimento.

A contenção em Kubernetes exige validar permissões de contas de serviço, remover pods privilegiados não autorizados, revisar objetos criados no período e inspecionar nós para persistência. Clusters devem reduzir permissões de contas de serviço usadas por aplicações que não precisam listar nós ou criar workloads privilegiados. Em CI/CD, os fluxos que usaram Trivy ou KICS durante as janelas associadas precisam de auditoria específica: tokens de runners, segredos de repositório, permissões de publicação e credenciais de provedores externos devem ser mapeados e rotacionados quando estiverem no alcance do job comprometido.

Depois da contenção, a organização deve validar a cadeia de build. Isso inclui reconstruir artefatos a partir de fontes confiáveis, comparar wheels instalados com artefatos esperados, revisar dependências transitivas e aplicar controles de proveniência para impedir que uma etapa de varredura ou uma ferramenta de segurança introduza alterações no pacote final. Alertas devem cobrir arquivos .pth inesperados, execução automática em inicialização do Python, criação de serviços systemd em diretórios de usuário e egress para domínios recém-observados em workloads que normalmente não fazem chamadas externas diretas.

  • Inventariar e remover litellm 1.82.7 e 1.82.8 de hosts, imagens, ambientes virtuais, caches e pipelines.
  • Isolar sistemas que executaram as versões afetadas antes de reconstruir ou recolocar workloads em produção.
  • Rotacionar credenciais disponíveis como variáveis de ambiente, arquivos de configuração, segredos Kubernetes e tokens de CI/CD.
  • Revisar logs DNS, proxy, EDR, Kubernetes Audit e systemd para sinais de exfiltração, persistência e criação de pods privilegiados.
  • Reduzir permissões de contas de serviço e identidades não humanas que não precisam de acesso a nós, criação de pods ou publicação de artefatos.

Postar um comentário

0 Comentários