Quem é responsável por verificar o conteúdo dos arquivos Python compilados quando uma bytecode entra em vigor?
A equipe de pesquisa do ReversingLabs descobriu um novo ataque ao PyPI que utiliza o código Python compilado para evitar a detecção, considerado o primeiro ataque a explorar a execução direta do arquivo PYC.
A equipe do ReversingLabs descobriu um novo tipo de ataque que utiliza código Python compilado para evitar a detecção. Esse é o primeiro ataque direcionado à cadeia de suprimentos que se aproveita da execução direta dos arquivos de código de bytes (PYC) do Python. Esse incidente ocorreu durante um aumento de envios maliciosos para o PyPI (Python Package Index), representando um risco para a cadeia de suprimentos, já que muitas ferramentas de segurança ignoram esse tipo de ataque.
No dia 17 de abril de 2023, o pacote suspeito chamado fshec2 foi relatado à equipe de segurança do PyPI e prontamente removido do repositório. A equipe de pesquisa identificou o pacote como suspeito, revelando detalhes sobre o método utilizado pelos invasores para evitar detecção e compartilhando informações sobre a infraestrutura de comando e controle (C2) do malware, bem como evidências de ataques bem-sucedidos.
Detectação: comportamentos incomuns
A equipe do ReversingLabs realiza verificações regulares em repositórios de código aberto, buscando arquivos suspeitos. Durante uma varredura, eles encontraram o pacote fshec2, que chamou atenção devido a comportamentos incomuns. Ao descompilar o arquivo, foram observados comportamentos suspeitos, como URLs referenciando um endereço IP e a criação de processos. Uma revisão manual revelou que o pacote consiste em três arquivos, sendo que o terceiro, “full.pyc”, revelou comportamentos intrigantes, revelando a verdadeira natureza do pacote.
Figura 01: Arquivos contendo funcionalidade de pacote
Desmascarando um loader incomum
Agentes de ameaças estão buscando constantemente maneiras de evitar a detecção por soluções de segurança. O ReversingLabs identificou um aumento no volume de malware no PyPI nos últimos meses, e técnicas de ofuscação, como a execução de código malicioso codificado em Base64, que foi identificada pela primeira vez em campanhas associadas aos autores do W4SP em novembro de 2022. Variações desse tipo de ataque, nas quais o código malicioso é incorporado no código, mas deslocado para além dos limites visíveis da tela (ocultando-o da visualização), ainda são comumente encontradas.
O pacote fshec2 adota uma abordagem diferente, colocando a funcionalidade maliciosa em um único arquivo de código de byte Python compilado, evitando o uso de ferramentas de ofuscação. Em vez disso, ele coloca a funcionalidade maliciosa em um único arquivo que contém código de byte Python compilado.
Como os ataques do Python (geralmente) funcionam
Os ataques maliciosos usando Python geralmente envolvem arquivos Python de texto simples, arquivos Python compilados e arquivos Python compilados em executáveis nativos. Na maioria dos casos, os executáveis são baixados e executados pelos arquivos Python de texto simples, através de infraestruturas externas, em campanhas maliciosas usando pacotes do PyPI.
No entanto, o pacote fshec2 adota uma abordagem diferente. Ele contém um arquivo Python compilado chamado full.pyc, que contém funcionalidade maliciosa. A importação de uma função em main.py desencadeia uma técnica de carregamento inédita, utilizando o Importlib, que evita a detecção por ferramentas de segurança. Essa escolha reforça a intenção de evitar a detecção e sugere que o Importlib é utilizado com esse propósito, mesmo que a biblioteca carregada por main.py permaneça inalterada.
Figura 02: Carregamento do módulo Python compilado de main.py
Após o carregamento do módulo, o método get_path é invocado (mostrado na figura 03). Utilizando a ferramenta ReversingLabs Software Supply Chain Security, a equipe de pesquisa conseguiu detectar e extrair esse código a partir do arquivo PYC descompilado. O método get_path não é encontrado no pacote fshec2 original. Esse método executa funções maliciosas, como coletar nomes de usuário, nomes de host e listagens de diretórios, que são comumente observadas em outros pacotes maliciosos do PyPI. Além disso, o método procura por comandos definidos para execução por meio de tarefas agendadas ou cronjobs, dependendo da plataforma do host.
Figura 03: O código descompilado extraído do arquivo de código de byte compilado full.pyc mostrando o conteúdo do método get_path().
Os comandos buscados pelo método get_path são, na verdade, outro script Python que pode ser alterado (mostrado na figura 04). Durante a análise, a equipe de pesquisa observou que o script baixou e executou um segundo script Python chamado cron_script, localizado no mesmo host. O cron_script possuía funcionalidade semelhante ao script encontrado em full.pyc, o módulo Python compilado fornecido com o pacote PyPI.
Essa abordagem torna o ataque fshec2 altamente adaptável. O arquivo full.pyc contém a funcionalidade para baixar comandos de um servidor remoto, enquanto os comandos baixados são inseridos no cron_script, permitindo o download periódico de novos comandos. Essa flexibilidade permite que os invasores modifiquem o conteúdo dos comandos, possibilitando que o malware sirva novas instruções.
Figura 04: Código responsável por baixar o arquivo cron_script
Um host da Web mal configurado desiste das mercadorias
Durante a investigação do host utilizado no ataque, foram descobertas informações interessantes devido a erros de configuração cometidos pelos autores do malware. Ao tentar acessar uma página inválida no host, em vez de receber um erro 404, os visitantes foram apresentados a uma página de um aplicativo Django que listava vários comandos. Essa exposição acidental revelou detalhes sobre o funcionamento interno do software malicioso. (Consulte a Figura 05)
Figura 05: locais da web descobertos
Felizmente para nós, o aplicativo Django estava configurado no modo de depuração, o que exibia mensagens de erro detalhadas que nos forneceram uma lista abrangente dos caminhos no host acessíveis. Alguns desses caminhos já foram vistos nos scripts baixados usados no ataque, mas havia novos caminhos que não tínhamos encontrado antes, como “admin”, “uploaded_files” e “download”. Infelizmente, a trilha esfriou lá, porque todos os três caminhos exigem autorização para acessar a funcionalidade das respectivas páginas.
Figura 06: Formulário de download de arquivo protegido por senha
Apesar da equipe de pesquisa não ter acesso à senha, erros de configuração revelaram alguns detalhes importantes sobre o malware. Por exemplo, um dos comandos permitia o download de arquivos por meio de uma ID específica. Além disso, nomes de arquivo foram expostos, sem a necessidade de autorização. A presença desses erros sugere que o ataque não foi realizado por um ator estatal patrocinado ou uma Ameaça Persistente Avançada (APT).
Embora não haja evidências suficientes para confirmar essa suposição, foi possível determinar que o ataque teve sucesso em alguns casos, infectando pelo menos dois alvos com nomes de usuário e hosts específicos. Além disso, os nomes de arquivos sugerem que o malware pode ter funcionalidades de keylogging. No entanto, não pode ser descartada a possibilidade de que haja outros canais de distribuição além do pacote fshec2 no PyPI que ainda não foram descobertos.
Figura 07: Nomes dos arquivos que podem ser baixados
Conclusão
O pacote malicioso fshec2 e a infraestrutura C2 associada destacam como os autores de malware podem evitar facilmente a detecção por meio da análise do código-fonte. Os scripts de carregador, como os encontrados neste pacote, contém apenas uma quantidade mínima de código Python e têm como objetivo principal carregar um módulo Python compilado, que acaba sendo malicioso. A ferramenta de segurança padrão do PyPI, o Inspector, atualmente não oferece recursos para analisar arquivos binários em busca de comportamentos maliciosos. Portanto, foi necessário descompilar o código compilado do arquivo .pyc para identificar sua funcionalidade suspeita e maliciosa.
Figura 08: ferramenta Inspector fornecida pela equipe de segurança do PyPI
A descoberta do código malicioso no pacote fshec2 destaca a importância crescente de detectar funções maliciosas, como get_path, para equipes de segurança e DevSecOps. Muitas soluções de segurança de aplicativos não se concentram na segurança da cadeia de suprimentos ou realizam apenas análises de código-fonte durante a inspeção de segurança do pacote. Isso permite que o malware, oculto no código de byte compilado do Python, passe despercebido pelas soluções de segurança tradicionais.
A ReversingLabs Software Supply Chain Security oferece suporte à análise estática e descompactação de diversos formatos de arquivo binário, incluindo o tipo de código de byte Python compilado encontrado nesse ataque. Essa capacidade de analisar esse tipo de arquivo permite que os defensores extraiam indicadores de intenção maliciosa, tornando mais fácil a avaliação da segurança dos pacotes.
Figura 09: Indicadores de comportamento e strings de rede extraídos do arquivo PYC descompilado usando o ReversingLabs Software Supply Chain Security.
Essa abordagem inclui detecção de criação de processos, execução de arquivos, coleta de informações confidenciais, presença de endereços IP e muito mais. A simples varredura do código-fonte de pacotes de código aberto não será suficiente para identificar esse tipo de ameaça. À medida que os invasores se tornam mais avançados e exploram suas vantagens, torna-se necessário utilizar ferramentas mais avançadas para garantir a segurança contínua de seu código e infraestrutura de desenvolvimento de software.
Indicadores de comprometimento (IoCs)
Servidor C2:
13.51.44.246