Downloader Python destaca problema de ruído na detecção de ameaças de código aberto

RL descobriu o que parecia ser um downloader malicioso no PyPI. Acabou sendo uma equipe vermelha – mas destaca um problema crescente para detecção de ameaças.

Os pesquisadores do ReversingLabs descobriram recentemente um pacote malicioso de código aberto: xFileSyncerx no Python Package Index (PyPI). O pacote, com cerca de 300 downloads registrados, continha componentes “limpadores” maliciosos separados. É uma ameaça à cadeia de abastecimento de código aberto? Tipo de. Uma investigação mais aprofundada realizada por nossa equipe revelou o fato de que o downloader e os limpadores foram criados por um profissional de segurança cibernética realizando testes de penetração da “equipe vermelha” no SOC de um cliente. 

Este incidente destaca um desafio crescente para as empresas que rastreiam (e derrotam) ameaças de código aberto. A saber: “ruído” na forma de grayware, como pacotes de teste, bem como pacotes maliciosos de baixa qualidade e baixa distribuição. À medida que mais atenção se volta para ameaças e ataques de código aberto e da cadeia de fornecimento, esta baixa relação sinal/ruído pode tornar mais difícil identificar e remediar ameaças legítimas de software de código aberto. 

Neste relatório discutiremos as descobertas de nossa pesquisa, bem como as implicações maiores para desenvolvedores e equipes de segurança, à medida que os “comuns” de código aberto ficam lotados de goodware, malware e grayware.

Discussão

Os pesquisadores do ReversingLabs fazem pesquisas regulares em repositórios de código aberto, como npm, GitHub e Python Package Index (PyPI), em busca de pacotes suspeitos e maliciosos, usando uma combinação de ferramentas internas e nossa família Spectra de tecnologia de segurança da cadeia de suprimentos de software, com base na análise de malware Spectra Core. motor. Entre outras coisas, verificamos uma vasta gama de repositórios públicos em busca de pacotes com características ou recursos que tendem a se correlacionar com códigos maliciosos ou comprometidos. 

Existem muitos exemplos de características suspeitas. Por exemplo, podemos notar que os pacotes são programados para se comunicar com servidores externos predefinidos – possível evidência de comando e controle malicioso. Ou eles podem ter dependências de pacotes proprietários ou de código aberto maliciosos conhecidos. 

Um “sinal de alerta” comum ao pesquisar pacotes de código aberto é o uso de ofuscação de código – embaralhar intencionalmente o código-fonte aberto para evitar que pessoas de fora possam determinar facilmente qual é o seu propósito. Por razões óbvias, usar ofuscação em um pacote de software público e de código aberto é muito suspeito. Se o código é gratuito, por que você (o desenvolvedor) está tentando esconder o que ele faz? 

Foi a presença de ofuscação de código que chamou nossa atenção para o mais recente pacote malicioso de código aberto.  

Pacote de limpador: s2.py

O pacote em questão é xFileSyncerx , um pacote Python que contém funcionalidade maliciosa: baixar malware de segundo estágio de uma URL remota. O pacote foi postado em abril por uma conta PyPI recém-criada e não continha dependências conhecidas. Conforme mencionado: foi sinalizado, em parte, porque continha código ofuscado. Posteriormente, foi determinado que era malicioso após uma inspeção manual feita por um pesquisador de ameaças do ReversingLabs. 

A ofuscação do código em questão estava relacionada a um URL de download malicioso codificado no pacote xFileSyncerx. Esse URL é armazenado como uma sequência de caracteres dentro de uma matriz para dificultar a detecção. Os valores na matriz são ainda mais ofuscados com vários deslocamentos bit a bit: operações aritméticas realizadas em números inteiros dentro do código que deslocam os bits para a esquerda ou para a direita. Eles são usados ​​para tornar uma sequência de bits – digamos, caracteres ASCII – mais difícil de decodificar. 

Antes de serem usados, os valores dentro de xFileSyncerx são “desofuscados” executando as mudanças bit a bit opostas . Quando desofuscado, o URL aponta para um arquivo hospedado em um repositório GitHub: hxxps: hxxps://raw.githubusercontent.com/d3duct1v/tester-of-trees/main/s2.py.

Código do downloader dentro do arquivo xfilesyncerx.py

Figura 1: Código do downloader dentro do arquivo xfilesyncerx.py

Como o próprio nome sugere, o arquivo S2.py é o malware de segundo estágio usado neste ataque. Ele é mantido ativamente por meio de uma conta GitHub com o identificador d3duct1v e tem mais de 20 commits desde que a versão inicial foi publicada em 17 de abril. 

As diferenças entre essas versões incluem correções de alguns erros de codificação e outras pequenas melhorias. Esse padrão de mudanças nos sugeriu que o malware s2.py está em fase inicial de desenvolvimento ou, talvez, que sirva como protótipo. No entanto, uma das versões inspecionadas pelos pesquisadores do ReversingLabs apresentava recursos de limpador totalmente funcionais.

Funcionalidade do limpador dentro do arquivo s2.py do segundo estágio

Figura 2: Funcionalidade do limpador dentro do arquivo s2.py de segundo estágio

Quando executado, s2.py percorre a hierarquia de arquivos encontrada dentro do diretório /home no sistema comprometido e usa o algoritmo de criptografia simétrica Fernet para criptografar todos os arquivos, exceto arquivos e diretórios ocultos, que começam com o caractere ponto (.). Esta exclusão provavelmente é feita para garantir que a funcionalidade SSH que o pacote s2.py usa posteriormente permaneça intacta. 

Um dos commits s2.py (Figura 3) revisados ​​pelo ReversingLabs revelou que inicialmente apenas os arquivos do diretório ‘.ssh’ foram excluídos da criptografia pelo malware. Essa funcionalidade foi posteriormente substituída por uma regra mais ampla que excluía todos os arquivos ocultos da criptografia.

python-downloader-figura-3


Figura 3: Verificação que impede a criptografia de arquivos ocultos

Uma mensagem escrita nos arquivos README do pacote criados na árvore de diretórios /home é reproduzida em um meme da Internet bem conhecido e sugere que o propósito do pacote s2.py é malicioso. Acontece que o malware criptografa, mas nunca extrai arquivos da máquina infectada, o que significa que um agente mal-intencionado que usa esse código nunca possuiria informações confidenciais de arquivos infectados com o malware s2.py, embora certamente pudesse interromper a operação do malware infectado. sistemas. 

Funcionalidade do limpador dentro do arquivo s2.py do segundo estágio

Figura 4: Funcionalidade do limpador dentro do arquivo s2.py de segundo estágio

Malware na porta?

À medida que nos aprofundamos no malware s2.py, a imagem se tornou mais interessante. Especificamente: 
observamos que após a criptografia dos arquivos no diretório /home, o malware tenta se espalhar pela rede local aproveitando o SSH para tentar se conectar a outros dispositivos usando credenciais codificadas. 

Se uma conexão SSH com um dispositivo de destino for estabelecida com sucesso, o malware de estágio 3 será baixado do mesmo repositório GitHub e executado no dispositivo de destino. O nome desse malware de terceiro estágio? Você adivinhou: s3.py. Esse malware de terceiro estágio é quase idêntico ao malware de estágio 2, exceto que contém apenas a funcionalidade de limpeza e não a funcionalidade de propagação. Em comparação com outros malwares que analisamos, o malware limpador em s2.py e s3.py era rudimentar, enquanto o histórico de commits dos pacotes mostrava o autor lutando com uma série de bugs que tornavam os pacotes não funcionais. 

Quanto à funcionalidade de divulgação: é aí que as coisas ficam interessantes. O login que o malware usa para tentar estabelecer uma conexão SSH é bellj1. Para nós, isso parecia ser uma referência às câmeras de campainha Bell J1 , câmeras de campainha sem fio baratas fabricadas pela empresa chinesa Shenzhen Joystek Intelligence Co. Também observamos uma lista codificada de endereços IP privados no malware do limpador – provavelmente um lista de possíveis ativos alvo em uma rede interna.

Verme IoT, certo? Errado

Com essas descobertas, uma ampla gama de explicações possíveis se estendeu diante de nós. O mais tentador foi a perspectiva de termos descoberto um worm (nascente) da Internet das Coisas (IoT) que tinha como alvo as câmeras Bell J1 implantadas em um ambiente (ou ambientes) específico. O uso de credenciais SSH codificadas sugeriu que o ator por trás desses pacotes maliciosos conseguiu obter conhecimento das credenciais de administrador padrão para aquele ambiente ou – possivelmente – que as próprias câmeras Bell J1 foram enviadas com credenciais SSH codificadas sob o nome de conta BellJ1. 

Tal cenário tem muitos precedentes. Credenciais codificadas são uma fonte comum de comprometimento de dispositivos IoT. Notoriamente, o botnet Mirai IoT, que tem sido associado a uma série de ataques de negação de serviço em grande escala, inicialmente se espalhou pela exploração de dezenas de credenciais padrão em dispositivos IoT, incluindo refrigeradores conectados, câmeras CCTV e torradeiras.  

Quanto aos endereços IP codificados que descobrimos: eles podem refletir um ambiente de teste padrão fornecido pelo fabricante e configurado pelo autor do malware que foi publicado acidentalmente no PyPI sem ser removido. Esses deslizes já aconteceram antes. E, sem mais informações do fabricante ou evidências de uma implantação “em estado selvagem” desse malware em câmeras comprometidas, não estava claro para nós o que estávamos vendo.

‘Lixo’ da equipe vermelha é igual a ruído de ameaça de código aberto

Com tantas perguntas sem resposta, decidimos nos aprofundar um pouco mais. Um colega meu entrou em contato com o indivíduo por trás da conta do mantenedor d3duct1v responsável pelo malware s2.py e s3.py no GitHub. Nossa(s) pergunta(s): você também criou o pacote xFileSyncerx e, em caso afirmativo, qual é o problema? 

Em nossa experiência, muitas vezes você não obtém resposta a perguntas como essa, especialmente quando a conta está conectada a um ator ou campanha mal-intencionada. Nesse caso, porém, recebemos uma resposta do autor, que explicou por e-mail que trabalhava como testador de penetração nos EUA e “sim”, também era o autor do pacote xFileSyncerx. Esse pacote foi criado “para um teste que estava executando deixei as URLs para os clientes (sp) SOC descobrirem”, explicaram. Os endereços IP em questão eram específicos do ambiente desse cliente. Quanto ao nome de usuário “BellJ1” e às campainhas inteligentes “Bell J1”? “100% coincidência”, garantiram-nos. 

O objetivo desses pacotes era testar o SOC (centro de operações de segurança) do cliente tanto em termos de sua capacidade de detectar a chamada suspeita para recuperar o malware de segundo e terceiro estágio, quanto de detectar (se possível) o movimento lateral conduzido pelo S2 .py conforme encontrou e infectou sistemas usando as credenciais SSH codificadas, indicou a pessoa por trás da conta d3duct1v. 

Além disso, a pessoa por trás da conta de mantenedor d3duct1v nos disse que estava planejando retirar o pacote antes de entrarmos em contato. Independentemente disso, notificamos os administradores do PyPI que removeram o pacote xFileSyncerx. Não está mais disponível para download. Os malwares s2.py e s3.py também foram removidos depois que o ReversingLabs contatou o(s) autor(es) por trás da conta d3duct1v. Eles não estão mais disponíveis para download.

Conclusão

Mesmo sem a confirmação por parte de seu autor, havia muitos motivos para duvidar que o xFileSyncerx fosse o próximo “Mirai” – o virulento worm da IoT – ou parte de algum ataque muscular à cadeia de suprimentos. 

Entre outras coisas, o código limitava-se a se espalhar entre um conjunto predefinido de hosts, sugerindo, na melhor das hipóteses, um ataque direcionado ou, mais provavelmente, um teste ou prova de conceito. Não houve nenhum esforço para “enfeitar” o código para parecer um pacote Python legítimo. Na verdade, a descrição do pacote xFileSyncerx no PyPI continha até uma mensagem de que este pacote não deveria ser usado. Depois, havia os nomes de pacotes transparentes: S2.py e S3.py para malware de segundo e terceiro estágios. Realmente? Portanto, ao saber que esses pacotes faziam parte de uma avaliação da equipe vermelha de um ambiente de cliente, muitas peças soltas se encaixaram. Afinal, o pacote xFileSyncerx Python é uma boa ferramenta para uma equipe vermelha implantar em um ambiente de cliente: ele exibe os recursos clássicos de um downloader e comportamento de propagação por meio do malware de segundo estágio: s2.py. Esses são aplicativos maliciosos básicos que exibem varredura de rede e movimento lateral. Se o seu cliente puder detectá-los, ele estará em uma boa posição para detectar outros pacotes verdadeiramente maliciosos.

Dito isso, não é comum encontrarmos funcionalidades de limpeza integradas às ferramentas do red team. Normalmente, as equipes vermelhas ficam satisfeitas em obter acesso a um sistema ou ambiente protegido e exfiltrar dados dele como prova de seu comprometimento bem-sucedido. Limpar o dispositivo e colocá-lo off-line é considerado muito perturbador para um ator amigável como um testador de penetração. 

Típico ou não, uma coisa que nossa descoberta do xFileSyncerx destaca é o problema do crescente “ruído” em repositórios de código aberto como PyPI, npm, GitHub e outros. À medida que o perfil das ameaças e ataques à cadeia de abastecimento aumenta na sequência de incidentes como os comprometimentos da SolarWinds, 3CX e outros, a população de goodware, malware e grayware está a explodir. E isso torna mais difícil para qualquer empresa que pretenda avaliar as ameaças à cadeia de abastecimento filtrar o “sinal” de todo esse ruído. 

Este pacote red team e inúmeros outros semelhantes à espreita em plataformas como PyPI – lixo e detritos deixados para trás em testes de penetração e outros exercícios – aumentam o desafio de identificar verdadeiras ameaças de código aberto. Uma sugestão poderia ser diretrizes e restrições mais claras em relação à publicação de pacotes de teste e grayware como esse em repositórios públicos e uma melhor demarcação deles para evitar confusão por parte dos desenvolvedores e das equipes de segurança.

Uma tragédia dos bens comuns (código aberto)?

O conceito que explica parte disto é o que os economistas chamam de “tragédia dos bens comuns” – uma tendência das comunidades que têm acesso irrestrito a um recurso de abusar e esgotá-lo, perseguindo os seus próprios interesses sem considerar a necessidade de preservar o recurso. para os outros. Podemos estar testemunhando uma dinâmica semelhante em repositórios de código aberto como npm, PyPI e GitHub, à medida que agentes de ameaças, caçadores de ameaças e outros os aproveitam de maneiras ilimitadas, sem se preocupar com o bem maior. 

Para as equipes de caça a ameaças, incidentes como esse mostram como o padrão está aumentando para a análise de ameaças de código aberto. Cinco anos atrás, qualquer malware encontrado à espreita em um repositório de código aberto era notícia nas manchetes. Hoje, a descoberta de recursos maliciosos escondidos no código pode indicar a descoberta de uma nova ameaça ou… algo mais. Cabe aos analistas de ameaças de código aberto fazer a escavação e a investigação necessárias para determinar a origem e a finalidade de um arquivo de aparência suspeita, para que a ameaça real que ele representa para as equipes de desenvolvimento e para a organização do usuário final seja devidamente compreendida. 

Indicadores de Compromisso (IOCs)

Indicadores de comprometimento (IoCs) referem-se a artefatos forenses ou evidências relacionadas a uma violação de segurança ou atividade não autorizada em uma rede ou sistema de computadores. Os IOCs desempenham um papel crucial nas investigações de segurança cibernética e nos esforços de resposta a incidentes cibernéticos, ajudando analistas e profissionais de segurança cibernética a identificar e detectar potenciais incidentes de segurança.

Os seguintes IOCs foram coletados como parte da investigação do ReversingLabs desta campanha da cadeia de fornecimento de software.

Pacotes PyPI:
nome do pacoteversãoSHA1
xFileSyncerx0.0.2e200d11a089e66840598b104b57e9758855031b3
URLs do GitHub:

hxxps://raw.githubusercontent.com/d3duct1v/tester-of-trees/main/s2.py
hxxps://raw.githubusercontent.com/d3duct1v/tester-of-trees/main/s3.py