Resumo
- SharpRhino é baseado no projeto de código aberto ThunderShell
- Distribuído para as vítimas como um instalador NSIS que descarrega scripts do PowerShell
- Os scripts do PowerShell contêm assemblies .NET codificados em contêineres
- O payload .NET é usado para se comunicar com o servidor C2
- Pode executar comandos remotamente
- O tráfego de rede é criptografado com RC4 e codificado no formato Base64
Introdução
O grupo de ameaças Hunters International, conhecido por suas operações de ransomware como serviço, começou a utilizar um novo malware RAT. O primeiro incidente com esse software foi detectado no início de agosto de 2024 e foi chamado de SharpRhino devido à sua linguagem C#. O trojan é entregue às vítimas como um software legítimo e concede acesso remoto à máquina da vítima. Usando esse software, os atacantes podem executar diferentes comandos e propagar outros malwares.
Detalhes técnicos
Visão geral
A amostra analisada é entregue às vítimas como um instalador que foi criado com o Nullsoft Scriptable Install System. Esse arquivo tem a descrição ‘Angryip.org’ e um certificado digital válido, mas o nome da empresa é falso e não existe.

Esse instalador contém um instalador adicional, um arquivo com proteção por senha e arquivos adicionais que serão usados durante a execução do malware.

Instalação
Quando executado, o exemplo descarrega todos os arquivos incorporados na pasta ‘C:\ProgramData\Microsoft\WindowsUpdate24’ e executa um arquivo ‘ipscan-3.9.1-setup.exe’, que é um instalador do software legítimo: Angry IP Scanner.

Enquanto o usuário está distraído com esse instalador, o malware extrai arquivos do arquivo morto UpdateFull.zip com proteção por senha. Para descompactar o arquivo, ele utiliza um programa 7za.exe incorporado. Na linha de comando, podemos ver a senha do arquivo morto:
C:\ProgramData\Microsoft\WindowsUpdate24\7za.exe x C:\ProgramData\Microsoft\WindowsUpdate24\UpdateFull.7z -pTG98HJerxsdqWE45 -oC:\ProgramData\Microsoft\WindowsUpdate24
O conteúdo do arquivo morto é o seguinte:

Após a extração, a amostra cria uma nova pasta — ‘C:\ProgramData\Microsoft\LogUpdateWindows’ — e copia os arquivos extraídos do arquivo morto para a nova pasta. O uso de duas pastas de instalação diferentes pode ajudar os atacantes a obter persistência e permanecer no sistema caso uma das pastas seja removida, pois os arquivos nessas pastas são semelhantes no processo de execução. Em seguida, ele adiciona uma nova chave de registro ao caminho ‘HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run’ que aponta para o arquivo ‘Microsoft.AnyKey.lnk’. Esse arquivo é um atalho e contém o próximo destino:
C:\ProgramData\Microsoft\LogUpdateWindows\Microsoft.AnyKey.exe abnormal c:\programdata\%username%0 cmd /c C:\ProgramData\Microsoft\LogUpdateWindows\LogUpdate.bat
O executável ‘Microsoft.AnyKey.exe’, que também é extraído do arquivo morto, é um programa legítimo que faz parte das ferramentas Node.js para o Visual Studio e é denominado ‘Microsoft.NodejsTools.PressAnyKey.exe’.
Execução
Os arquivos ‘LogUpdate.bat’ e ‘WindowsUpdate.bat’ têm a mesma funcionalidade, mas carregam arquivos diferentes.

Os arquivos ‘Wiaphoh7um.t’ e ‘kautix2aeX.t’ contêm dados ofuscados. Os dados brutos e a chave são diferentes para esses arquivos, mas os dados resultantes serão os mesmos. Após o processo de decodificação, a amostra define esses dados como um assembly .NET e chama um método com alguns parâmetros.

Após o despejo de todos os dados do script, podemos observar as variáveis a seguir:
As variáveis $var1, $var2, $var3 determinam as assemblies referenciadas e quando concatenadas formam a próxima string:
System.Drawing.dllSystem.Web.Extensions.dllSystem.Windows.Forms.dll
$var4 é diferente para cada arquivo e contém um endereço de servidor C2. A seguir, temos uma tabela representando os argumentos que são utilizados na chamada de assembly .NET para cada arquivo:

‘$fjwZrHB1k2RF’ representa um assembly do .NET que é carregado na memória. Após o despejo dos dados, podemos observar o código C#. O script do PowerShell chama uma função do namespace ‘Bzxmlpi’ e da classe ‘OyrWkb’. No início dessa classe, podemos observar algumas importações adicionais e nomes de variáveis ilegíveis.

Na verdade, esse arquivo é uma versão modificada do projeto de código aberto “ThunderShell”. Foram feitas várias alterações no projeto de origem:
- Foram removidas as funções de carregamento de keylogger, captura de tela e .NET Assembly, bem como os comandos do servidor que representavam essas funções.
- Todos os nomes de classes, funções e variáveis foram renomeados.
- Adicionados valores padrão que serão usados se o payload for executado sem argumentos.

Essa função gera primeiro uma cadeia de 16 bytes aleatória. Ao inicializar a classe Random, a amostra utiliza a data, a hora e a ID do processo atual como semente. Em seguida, ele obtém algumas variáveis de ambiente, como COMPUTERNAME, USERDOMAIN e USERNAME. Todos esses dados serão formatados:

Como resultado, a próxima cadeia é gerada:

Em seguida, a amostra passa essa string para uma função que a enviará para o servidor. Aqui, ele criptografa os dados usando uma cifra RC4 com uma chave que foi passada como segundo argumento.

Após o processo de criptografia, ele adiciona alguns dados à solicitação e codifica a cadeia criptografada no formato Base64. Todos esses dados são então enviados para o servidor.

Nessa primeira conexão, a resposta do servidor é ignorada. Quando a amostra entra em um loop, ela se conecta ao servidor novamente, mas ambos os argumentos são ‘null’. Em seguida, a resposta é salva e comparada com os valores salvos. Se o comando ‘delay’ for recebido, a amostra toma um argumento adicional e altera o valor que será passado para a função sleep. Se o comando ‘exit’ fosse obtido, ele interromperia o loop e terminaria a execução. Se ele obtiver quaisquer dados que não sejam “delay” ou “exit”, ele criará uma nova thread com uma função que tomará os dados obtidos como argumento. Todas essas ações serão repetidas com um intervalo de 95 segundos entre cada iteração do loop.

A resposta que vem do servidor é passada para a função de desserialização na classe ‘zWxFlnVASjHYb’, que captura e armazena os dados a seguir: ‘UUID’, ‘ID’ e ‘Data’.

Servidor C2
Embora o link que foi apresentado na amostra já estivesse offline, podemos usar o servidor do projeto de origem para ver como a comunicação funciona. Primeiro, precisamos alterar a configuração do servidor. Ele contém vários campos, incluindo o endereço IP do servidor, a chave de criptografia, as configurações da interface gráfica do usuário e as configurações de HTTP e HTTPS. Em segundo lugar, precisamos alterar os parâmetros ‘callback-url’, ‘gui-host’ e ‘encryption-key’. Vamos pegar os parâmetros da chave de criptografia de uma amostra do SharpRhino.

O servidor é uma aplicação Python e requer um servidor Redis em execução. Após a inicialização, ele exibe algumas informações sobre o servidor.

Isso inclui um endereço de interface de usuário da Web. Quando aberto, o usuário primeiro precisa entrar. Embora não importe qual nome de usuário seja inserido, a senha deve ser utilizada a partir do arquivo de configuração de TI. Quando você entra, a seção dashboard é exibida. Ela contém informações sobre sessões e logs.

O payload pode ser criado na interface de usuário gráfica (GUI) da Web. O endereço IP do servidor deve ser fornecido, bem como o tipo de payload.

Após escolher uma sessão, o invasor pode interagir com ela. Ao digitar ‘help’, são exibidos todos os comandos suportados que podem ser utilizados na sessão.

Comunicações C2
Esses comandos têm strings predefinidas que serão anexadas aos dados que o invasor insere como argumentos. Por exemplo, o uso de ‘shell [comando]’ irá anexar ‘cmd.exe /c’ ao início da string que será enviada. Outro exemplo é o comando ‘ps’, que enviará o script do PowerShell para o cliente:

O comando chega ao cliente criptografado com RC4 e codificado no formato Base64. Ele contém os parâmetros ID e UUID, onde ID é o ID do cliente e UUID é o ID do comando.

Todos esses dados são passados para a nova thread. A função nesta thread usa módulos do PowerShell para executar comandos fornecidos.

Usando o pipeline, a amostra obtém a saída do comando executado. Esses dados serão então criptografados e enviados de volta para o servidor.

Conclusão
O ThunderShell, um antigo projeto de código aberto que foi atualizado pela última vez há quase quatro anos, foi usado pela Hunters International para entregar malware às vítimas. Ele chega como um instalador de utilitário do Angry IP Scanner, que descarrega e executa scripts maliciosos do PowerShell. Usando as capacidades do PowerShell, esses scripts executam assemblies .NET codificados, de modo que não é necessário trazer nenhum executável compilado adicional — o código malicioso é chamado e executado na memória.
Embora o código original tenha sido modificado, ele manteve sua funcionalidade principal: a execução remota de comandos em sistemas de destino. Esse é o perigo desses projetos de código aberto. Eles costumam ser desenvolvidos para fins educacionais ou de teste de invasão, mas são usados para ataques reais.
Detectado pela Acronis

