Desvendando Malware em Python: Um Guia de Reversing para Iniciantes
Analistas de cibersegurança frequentemente encontram malware escrito em Python, que se tornou um padrão para atacantes. Este artigo detalha um pipeline eficaz para analisar e reverter esses tipos de ameaças, desde a identificação do empacotador até a descompilação e análise estática do código.
MundiX News·27 de junho de 2026·10 min de leitura·👁 1 views
Malware escrito em Python deixou de ser uma novidade para se tornar uma ferramenta comum nas mãos de cibercriminosos. Atacantes têm cada vez mais optado por Python no desenvolvimento de malwares, especialmente para loaders, stealers e ferramentas de pós-exploração. As razões para essa popularidade são claras: os desenvolvedores maliciosos não precisam gastar semanas construindo infraestruturas de desenvolvimento, pois muitas funcionalidades já estão disponíveis em módulos Python prontos, como requests para rede, pywin32 para a API do Windows, sqlite3 para bancos de dados locais e cryptography para criptografia. Além disso, um único script Python funciona perfeitamente em Windows, Linux e macOS, eliminando a necessidade de recompilação. Ferramentas como PyInstaller, Nuitka e cx_Freeze empacotam o interpretador, as dependências e o bytecode em um único executável. Para o usuário final, isso se apresenta como um programa, mas para o analista, é essencialmente um diretório arquivado. A profundidade desse empacotamento varia; por exemplo, cx_Freeze pode não embutir todas as bibliotecas dinâmicas no executável, mas as coloca em um diretório separado, tornando o malware menos comum em campanhas reais, pois sem os arquivos DLL ou SO, o programa falha. Outras soluções como py2exe seguem um princípio semelhante ao PyInstaller, mas seu desenvolvimento é menos ativo, e muitas ferramentas automatizadas para extração de arquivos PYC são otimizadas para versões mais antigas de suas compilações.
Esses malwares em Python são encontrados em diversas aplicações, desde simples infostealers até plataformas Malware-as-a-Service (MaaS) como o CrystalX RAT, distribuído em chats privados do Telegram. O CrystalX RAT inclui funcionalidades como C2 via WebSocket, roubo de credenciais através do ChromeElevator (o mesmo que foi analisado pelo autor), injeção de extensões em navegadores, substituição de carteiras de criptomoedas na área de transferência e anti-debugging. É importante mencionar o Nuitka, que formalmente é um compilador que traduz código Python para C/C++ e, em seguida, compila um executável completo. Analisar um arquivo compilado com Nuitka é mais desafiador, pois o analista recebe um programa completo que requer métodos de engenharia reversa clássica, em vez de um conjunto de bytecode Python. A versão comercial do Nuitka oferece mecanismos adicionais de ofuscação e proteção de dados. No entanto, a experiência do autor indica que malwares baseados em Nuitka são significativamente menos comuns do que aqueles empacotados com PyInstaller. Até mesmo grupos APT avançados ocasionalmente utilizam módulos Python para acesso inicial ou movimentação lateral. Estimar a proporção exata desses malwares no volume total de ataques é difícil, pois os vírus em Python frequentemente atuam apenas como um componente auxiliar em ataques mais complexos.
A maioria dos empacotadores Python, incluindo o PyInstaller, opera de maneira semelhante. Eles primeiro compilam os scripts de origem em bytecode (.pyc) e, em seguida, incluem tudo, juntamente com o interpretador e as bibliotecas necessárias, na compilação final. Esses empacotadores podem gerar um único arquivo executável ou um diretório com as dependências. Para o analista de ameaças, isso significa que o trabalho é feito com bytecode Python, não com o código-fonte original. As compilações Python possuem outras características distintas: primeiramente, esses arquivos são geralmente grandes; um infostealer simples de 80-100 MB é normal, não devido à ofuscação, mas ao tamanho real do interpretador e das bibliotecas. Em segundo lugar, esse arquivo pode ser descompactado em segundos. Diferente de C/C++ (com ferramentas como Themida ou VMProtect), não há empacotamento complexo com máquinas virtuais. É necessário apenas extrair o bytecode e as configurações. O pipeline de análise desenvolvido pelo autor, testado em vários samples, começa com a identificação do tipo de empacotador, observando o tamanho do arquivo, verificando imports no cabeçalho PE (usando strings, PEview, Detect It Easy) e procurando por strings como PyInstaller, python3x.dll, pyi_runtime, MEI. Se esses indicadores são encontrados, o sample é identificado como uma compilação PyInstaller. Em seguida, o utilitário open-source Pyinstxtractor é usado para extrair os arquivos .pyc, configuração e bibliotecas. O próximo passo é encontrar o módulo alvo, focando em arquivos que não pertencem à biblioteca padrão do Python, com nomes suspeitos (victim_hidden.pyc, core_logic.pyc, update.pyc) ou que importam módulos de rede, criptografia, manipulação de registro ou sistema de arquivos. O bytecode é então descompilado, geralmente com pycdc, embora outras ferramentas como uncompyle6 ou decompyle3 possam ser necessárias para obter um resultado mais legível. Finalmente, o código descompilado é analisado estaticamente em busca de decodificação de strings (base64.b64decode, codecs.decode, zlib.decompress), requisições de rede (requests, socket, urllib, websocket) e execução de código (exec, eval, subprocess.run, os.system), além de interações com o sistema de arquivos e registro.
O autor testou esse pipeline em dois malwares. O primeiro foi o ChromeElevator.exe, um utilitário que rouba credenciais de navegadores baseados em Chrome. Ao usar o Pyinstxtractor, o arquivo victim_hidden.pyc foi identificado. Após a descompilação com pycdc, o código revelou strings ofuscadas com longas sequências base64 que eram descomprimidas com zlib.decompress(). A descompressão revelou um script Python claro, detalhando a lógica do malware. A comunicação com o C2 envolvia o envio da string "VICTIM" para identificação, seguido por um identificador no formato "Nome do usuário"@"Nome do host":"diretório atual". O malware esperava comandos como "REFRESH_PROMPT" para atualizar o estado da sessão, "cd" para mudar o diretório de trabalho, ou qualquer outra string interpretada como um comando do sistema operacional, cujo output era enviado de volta ao servidor. A comunicação era realizada via TCP bruto, utilizando sockets de rede, essencialmente um shell interativo rudimentar sobre TCP. A carga útil era criptografada com Fernet antes do envio, adicionando um cabeçalho de serviço. O segundo teste foi com um infostealer que rouba senhas de navegadores baseados em Chrome, localizando e extraindo bancos de dados de senhas, descriptografando-os e enviando os dados para um chat do Telegram via Telegram Bot API. Apesar de ser um malware simples, é eficaz e frequentemente utilizado em ataques. A análise confirmou a compilação PyInstaller através de marcadores como python312.dll, pyi_runtime e o diretório _MEI. O arquivo stealer.pyc foi identificado e descompilado. A descompilação apresentou alguns desafios devido a problemas de compatibilidade do pycdc com Python 3.12, mas o código foi recuperado de forma legível. A análise estática revelou que o infostealer se conecta ao banco de dados do Chrome Login Data, extrai e descriptografa as credenciais salvas, e as envia ao atacante. O tratamento de erros com blocos try/except na função de descriptografia garante que senhas não descriptografáveis retornem None, evitando a inclusão de dados inválidos no relatório. A formatação dos dados para envio via Telegram Bot API foi detalhada, incluindo o token do bot e o chat_id, e a função send_telegram_message(). A iteração sobre os caminhos dos perfis do Chrome e a verificação da existência de arquivos foram realizadas em main() usando os.path.expanduser('~'). O código foi considerado simples e sem ofuscações complexas.
Em suma, a análise de malware em Python não exige imersão em linguagens de baixo nível como assembly. Sua principal vulnerabilidade reside na própria arquitetura: o bytecode é relativamente fácil de extrair, e a ofuscação geralmente se limita à criptografia de strings e renomeação de variáveis. A abordagem descrita neste artigo cobre a maioria dos casos típicos. Embora não seja eficaz contra empacotadores customizados ou ofuscação agressiva, mesmo essas amostras mais complexas possuem pontos fracos. A estrutura de empacotamento via PyInstaller, por exemplo, deixa rastros suficientes para a análise. A engenharia reversa de malwares em Python, embora possa exigir mais tempo e esforço, é acessível e recompensadora para analistas de ameaças.
🛡️⚡
Pare de pesquisar. Comece a hackear.
O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.
Sem cartão para começar · Planos a partir de R$49/mês
Malware escrito em Python deixou de ser uma novidade para se tornar uma ferramenta comum nas mãos de cibercriminosos. Atacantes têm cada vez mais optado por Python no desenvolvimento de malwares, especialmente para loaders, stealers e ferramentas de pós-exploração. As razões para essa popularidade são claras: os desenvolvedores maliciosos não precisam gastar semanas construindo infraestruturas de desenvolvimento, pois muitas funcionalidades já estão disponíveis em módulos Python prontos, como requests para rede, pywin32 para a API do Windows, sqlite3 para bancos de dados locais e cryptography para criptografia. Além disso, um único script Python funciona perfeitamente em Windows, Linux e macOS, eliminando a necessidade de recompilação. Ferramentas como PyInstaller, Nuitka e cx_Freeze empacotam o interpretador, as dependências e o bytecode em um único executável. Para o usuário final, isso se apresenta como um programa, mas para o analista, é essencialmente um diretório arquivado. A profundidade desse empacotamento varia; por exemplo, cx_Freeze pode não embutir todas as bibliotecas dinâmicas no executável, mas as coloca em um diretório separado, tornando o malware menos comum em campanhas reais, pois sem os arquivos DLL ou SO, o programa falha. Outras soluções como py2exe seguem um princípio semelhante ao PyInstaller, mas seu desenvolvimento é menos ativo, e muitas ferramentas automatizadas para extração de arquivos PYC são otimizadas para versões mais antigas de suas compilações.
Esses malwares em Python são encontrados em diversas aplicações, desde simples infostealers até plataformas Malware-as-a-Service (MaaS) como o CrystalX RAT, distribuído em chats privados do Telegram. O CrystalX RAT inclui funcionalidades como C2 via WebSocket, roubo de credenciais através do ChromeElevator (o mesmo que foi analisado pelo autor), injeção de extensões em navegadores, substituição de carteiras de criptomoedas na área de transferência e anti-debugging. É importante mencionar o Nuitka, que formalmente é um compilador que traduz código Python para C/C++ e, em seguida, compila um executável completo. Analisar um arquivo compilado com Nuitka é mais desafiador, pois o analista recebe um programa completo que requer métodos de engenharia reversa clássica, em vez de um conjunto de bytecode Python. A versão comercial do Nuitka oferece mecanismos adicionais de ofuscação e proteção de dados. No entanto, a experiência do autor indica que malwares baseados em Nuitka são significativamente menos comuns do que aqueles empacotados com PyInstaller. Até mesmo grupos APT avançados ocasionalmente utilizam módulos Python para acesso inicial ou movimentação lateral. Estimar a proporção exata desses malwares no volume total de ataques é difícil, pois os vírus em Python frequentemente atuam apenas como um componente auxiliar em ataques mais complexos.
A maioria dos empacotadores Python, incluindo o PyInstaller, opera de maneira semelhante. Eles primeiro compilam os scripts de origem em bytecode (.pyc) e, em seguida, incluem tudo, juntamente com o interpretador e as bibliotecas necessárias, na compilação final. Esses empacotadores podem gerar um único arquivo executável ou um diretório com as dependências. Para o analista de ameaças, isso significa que o trabalho é feito com bytecode Python, não com o código-fonte original. As compilações Python possuem outras características distintas: primeiramente, esses arquivos são geralmente grandes; um infostealer simples de 80-100 MB é normal, não devido à ofuscação, mas ao tamanho real do interpretador e das bibliotecas. Em segundo lugar, esse arquivo pode ser descompactado em segundos. Diferente de C/C++ (com ferramentas como Themida ou VMProtect), não há empacotamento complexo com máquinas virtuais. É necessário apenas extrair o bytecode e as configurações. O pipeline de análise desenvolvido pelo autor, testado em vários samples, começa com a identificação do tipo de empacotador, observando o tamanho do arquivo, verificando imports no cabeçalho PE (usando strings, PEview, Detect It Easy) e procurando por strings como PyInstaller, python3x.dll, pyi_runtime, MEI. Se esses indicadores são encontrados, o sample é identificado como uma compilação PyInstaller. Em seguida, o utilitário open-source Pyinstxtractor é usado para extrair os arquivos .pyc, configuração e bibliotecas. O próximo passo é encontrar o módulo alvo, focando em arquivos que não pertencem à biblioteca padrão do Python, com nomes suspeitos (victim_hidden.pyc, core_logic.pyc, update.pyc) ou que importam módulos de rede, criptografia, manipulação de registro ou sistema de arquivos. O bytecode é então descompilado, geralmente com pycdc, embora outras ferramentas como uncompyle6 ou decompyle3 possam ser necessárias para obter um resultado mais legível. Finalmente, o código descompilado é analisado estaticamente em busca de decodificação de strings (base64.b64decode, codecs.decode, zlib.decompress), requisições de rede (requests, socket, urllib, websocket) e execução de código (exec, eval, subprocess.run, os.system), além de interações com o sistema de arquivos e registro.
O autor testou esse pipeline em dois malwares. O primeiro foi o ChromeElevator.exe, um utilitário que rouba credenciais de navegadores baseados em Chrome. Ao usar o Pyinstxtractor, o arquivo victim_hidden.pyc foi identificado. Após a descompilação com pycdc, o código revelou strings ofuscadas com longas sequências base64 que eram descomprimidas com zlib.decompress(). A descompressão revelou um script Python claro, detalhando a lógica do malware. A comunicação com o C2 envolvia o envio da string "VICTIM" para identificação, seguido por um identificador no formato "Nome do usuário"@"Nome do host":"diretório atual". O malware esperava comandos como "REFRESH_PROMPT" para atualizar o estado da sessão, "cd" para mudar o diretório de trabalho, ou qualquer outra string interpretada como um comando do sistema operacional, cujo output era enviado de volta ao servidor. A comunicação era realizada via TCP bruto, utilizando sockets de rede, essencialmente um shell interativo rudimentar sobre TCP. A carga útil era criptografada com Fernet antes do envio, adicionando um cabeçalho de serviço. O segundo teste foi com um infostealer que rouba senhas de navegadores baseados em Chrome, localizando e extraindo bancos de dados de senhas, descriptografando-os e enviando os dados para um chat do Telegram via Telegram Bot API. Apesar de ser um malware simples, é eficaz e frequentemente utilizado em ataques. A análise confirmou a compilação PyInstaller através de marcadores como python312.dll, pyi_runtime e o diretório _MEI. O arquivo stealer.pyc foi identificado e descompilado. A descompilação apresentou alguns desafios devido a problemas de compatibilidade do pycdc com Python 3.12, mas o código foi recuperado de forma legível. A análise estática revelou que o infostealer se conecta ao banco de dados do Chrome Login Data, extrai e descriptografa as credenciais salvas, e as envia ao atacante. O tratamento de erros com blocos try/except na função de descriptografia garante que senhas não descriptografáveis retornem None, evitando a inclusão de dados inválidos no relatório. A formatação dos dados para envio via Telegram Bot API foi detalhada, incluindo o token do bot e o chat_id, e a função send_telegram_message(). A iteração sobre os caminhos dos perfis do Chrome e a verificação da existência de arquivos foram realizadas em main() usando os.path.expanduser('~'). O código foi considerado simples e sem ofuscações complexas.
Em suma, a análise de malware em Python não exige imersão em linguagens de baixo nível como assembly. Sua principal vulnerabilidade reside na própria arquitetura: o bytecode é relativamente fácil de extrair, e a ofuscação geralmente se limita à criptografia de strings e renomeação de variáveis. A abordagem descrita neste artigo cobre a maioria dos casos típicos. Embora não seja eficaz contra empacotadores customizados ou ofuscação agressiva, mesmo essas amostras mais complexas possuem pontos fracos. A estrutura de empacotamento via PyInstaller, por exemplo, deixa rastros suficientes para a análise. A engenharia reversa de malwares em Python, embora possa exigir mais tempo e esforço, é acessível e recompensadora para analistas de ameaças.
📤 Compartilhar & Baixar
🧰 Ferramentas recomendadas
Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.