
Para aqueles que já jogaram o suficiente com os
quebra-cabeças crackme , trouxemos um novo Trojan. Na natureza, o Hancitor downloader ainda é encontrado em seu habitat natural - correspondências de spam. Atualmente, ele é usado ativamente para baixar o trojan Panda banking, que é uma modificação do notório Zeus.
Numa noite fria de verão, o encontramos cara a cara, olhando para o spam de e-mail. Se você gosta de assistir ao que o malware tem por trás, leia nossa nova análise inversa.
Nosso documento malicioso é assim:

Por padrão, as macros estão bloqueadas, então o sistema avisa: "As macros foram desativadas". No entanto, o conteúdo da mensagem diz que as macros devem ser incluídas. Bem, vamos lá. Depois de clicar no botão Ativar conteúdo, o computador está infectado. Agora vamos ver que tipo de macro é executada e como exatamente a infecção ocorre. Isso pode ser feito imediatamente no Word, indo para a guia Exibir-> Vacros \ Exibir macros.

Você pode fazer de forma mais profissional - use o olevba do pacote oletools. Você pode instalar o pacote lá no link. Em seguida, digite olevba doc_file –c –decode> source.txt e obtenha a fonte da macro.

Pelo código, quero dizer imediatamente que o Trojan pertence à classe de downloaders. O script apenas esvazia de algum lugar para os Malwara. Para provar isso, vamos decodificar cadeias base64. É mais conveniente fazer isso imediatamente através do hiew, para não copiar e colar centenas de vezes. Para fazer isso, usamos um plug-in especial, descrito
aqui . Aqui está o que aconteceu:

Este é um script malicioso, dividido em duas partes e salvo como 1.hta. Em princípio, não estamos particularmente interessados em como isso funciona. É tudo bastante comum. O único ponto importante é determinar a URL na qual o arquivo malicioso é baixado. Vamos tentar encontrá-lo, pois essas informações podem ser úteis para a
segurança . Eles podem adicionar regras de rede para bloquear solicitações nesses URLs, o que pode salvar a empresa de infecções.
Ha! Não há links. Mas de onde vem o arquivo 6.exe, que inicia o 1.hta? É hora de dar uma olhada novamente no nosso arquivo dock no hiew, mas com mais cuidado:

Sim, um exe-shnik está incorporado no documento de encaixe. Sim, e fortemente embalado. Vamos explicar o que está acontecendo. A macro solta o script 1.hta malicioso na pasta Temp e o inicia, e o 1.hta, por sua vez, inicia o 6.exe em seu diretório. É claro que o 6.exe é o mesmo pacote PE-shnik que vemos na tela. Mas agora estamos nos perguntando como o 6.exe cai em% temp%. E isso acontece por causa de um recurso interessante no pacote Microsoft Office. O fato é que, em qualquer documento OLE, qualquer outro arquivo no formato Ole10Native pode ser incorporado.
Se for esse o caso, na inicialização, o próprio MS-Office descarta o arquivo criado dessa maneira na pasta% temp% com o nome especificado no cabeçalho da estrutura Ole10Native. Vamos dar uma olhada neste objeto. Fomos ajudados pelo plugin ao gerenciador de FAR -
OLE2Viewer . Abrimos nosso documento malicioso no plug-in, acesse o diretório ObjectPool \ _1593522492 e veja o seguinte:

Copie este arquivo (Ole10Native) e abra em hiew.

Aqui, vemos sob que nome nosso objeto OLE - 5c.pif será solto na pasta% temp%. Agora, de volta à nossa macro. Sua tarefa é lançar um exe-shnik bêbado.

De fato, para ser mais preciso, a macro nem sempre inicia o arquivo descartado através do 1.hta, mas também é assim: Shell “cmd.exe / c executa ping localhost -n 100 &&” & Environ (“Temp”) & "\ 6 .pif ", vbHide

O método de inicialização, como vemos, depende da presença dos seguintes processos no sistema: bdagent.exe e PSUAMain.exe. Por que, então, você precisa executar ping localhost -n 100? E esse é um truque grego antigo para criar um atraso artificial, apenas por precaução. Geralmente, suas variações são usadas para remoção automática.
Nesta fase, examinamos a operação de um documento malicioso. Ficou claro para nós que o documento em si não pertence a malware do tipo Trojan-Downloader, como parecia à primeira vista, mas é adequado para o tipo Trojan-Dropper. Aqui está o que aconteceu na inicialização:

Agora resta desmontar a carga útil. Já percebemos que nosso cavalo de Troia está empacotado, por isso devemos desempacotá-lo primeiro. Geralmente esse processo é dividido em duas etapas:
1. Removendo o dump descompactado + restaurando a tabela de importação.
2. Análise e purificação de variáveis globais.
Precisamos do segundo estágio, porque existem muitas funções da API que, como resultado de seu trabalho, retornam valores não repetitivos para nós. Por exemplo, o CreatHeap retornará um descritor de heap para nós, que será usado posteriormente para o trabalho. Muitas vezes, há verificações de tipo no código:
se o descritor de heap == 0, obtenha o descritor de heap, caso contrário, use um já inicializado . Porém, no momento do despejo, a variável que continha o descritor fornecido já havia sido inicializada por ele e naquele momento o descritor era válido. Quando tentamos iniciar o despejo, a variável com nosso descritor conterá o valor antigo, ou seja, não é igual a 0, o que significa que o teste será aprovado.
Depois disso, assim que o programa tentar usar esse descritor, o sistema operacional lançará uma exceção e o programa falhará com um erro. Portanto, para evitar isso, você precisa zerar essas variáveis. Eles geralmente estão localizados em uma seção gravável dos dados. Provavelmente, você sugere abrir esta seção no editor hexadecimal e sobrescrever tudo com zeros? Você está parcialmente certo, mas não deve tomar ações precipitadas. Existem trojans que verificam variáveis não em 0, mas em um DWORD aleatório. E, dependendo se o teste está sendo testado ou não, várias ações são tomadas. Você não precisa ir longe para obter exemplos. Basta olhar para o
Cridex (recentemente desapareceu em algum lugar dos radares, aparentemente foi completamente atualizado para o EMOTETA).
Então, vamos executar nossa amostra (em uma máquina virtual, é claro). Também é desejável que o tráfego que sairá da máquina virtual passe por uma VPN.
Lançamos nosso Trojan, e ele simplesmente trava no processo. Ótimo! Normalmente, os cavalos de Troia fazem as coisas rapidamente e, em seguida, terminam imediatamente e se auto-destróem. Portanto, você precisa procurar lugares no código responsável por essas ações, colocar uma pausa neles e depois despejar. No nosso caso, podemos fazer assim.
Para o dump, usamos o maravilhoso utilitário - Process Dump, que pode ser encontrado
aqui . Esse utilitário não apenas encontra todos os módulos executáveis ocultos e os despeja, mas também restaura a própria tabela de importação. O utilitário deve ser executado como administrador da seguinte maneira: pd / pid xxxx, em que xxxx é o ID do processo de Trojan. Depois disso, o utilitário fará o dump de todos os módulos do processo. Removemos os extras e é isso que resta:

O nome do arquivo executável do processo Trojan é 1.exe. Acontece que o cavalo de Troia descompactado estava localizado em 0x2C0000. Abra-o no hiew:

Apenas um olho feliz! Agora o arquivo está descompactado, está claramente visível. A tabela de importação também foi reconhecida. Vamos abri-lo no IDA-PRO.

Nós já renomeamos algumas funções enquanto classificamos a amostra. A primeira coisa que o Trojan começa é determinar o endereço de carregamento do seu módulo. E realmente: como ele sabia em que endereço seu esboço foi descompactado? Isso é feito com uma antiga técnica comprovada - inverter uma página de memória em 0x1000 em relação ao endereço atual até encontrarmos os bytes "MZ". Isso funciona porque os módulos executáveis sempre carregam o sistema operacional em um endereço múltiplo de 0x1000. Confira você mesmo. No nosso caso, um limite de 100 descargas é definido.

Se alguém não entender onde há uma inversão, aqui é onde:
resultado + = 0xFFFFF000 é equivalente a resultado - = 0x1000.
Depois de receber o endereço de download do seu módulo, o trojan descompactado recebe os endereços das funções necessárias para sua operação. Para começar, os endereços de duas funções são pesquisados - LoadLibraryA e GetProcAddress. Conhecendo os endereços dessas funções, você pode usá-los para obter todo o resto. Essas funções estão na biblioteca kernel32. Seu endereço é obtido através da leitura do primeiro (zero - ntdll, primeira base do kernel, etc.) da lista de anéis que descreve todos os módulos carregados na ordem de inicialização com a estrutura _LDR_DATA_TABLE_ENTRY. O ponteiro para a lista é puxado do PEB.

Após receber o endereço kernel32.dll (a partir do Windows 7 - kernelBase.dll), o cavalo de Troia pode analisar manualmente sua tabela de exportação e encontrar as duas funções necessárias, que são previsíveis na sub-rotina sub_EF1E60.

Agora, dê uma olhada na função que chamamos de getHeap.

Aqui estamos observando apenas a situação descrita acima. No momento do despejo, a variável hHeap continha um valor de 600000h. Portanto, GetProcessHeap não será chamado. Em vez disso, o programa irá para o rótulo loc_EF11DD, onde HeapAlloc é chamado com um identificador inválido, o que nos dará um erro. Portanto, pegamos o editor hexadecimal e zeramos esse número. Contamos seis lugares semelhantes.
Em seguida, a diversão começa. O cavalo de Troia gera um ID de "cliente" exclusivo com base no número de série do disco rígido e no endereço MAC. Informações recebidas aqui:

Também temos o seguinte: endereço IP, versão do SO, nome da rede e nome de usuário. Com base nisso, uma solicitação HTTP é gerada no painel de administração, cujo endereço ainda não sabemos. Não está nas linhas (mesmo na forma descompactada). Mas não está lá, porque está criptografado na configuração. Seu endereço pode ser extraído do código:

A configuração pesa 0x2008 bytes e tem o seguinte formato: os primeiros 8 bytes são a chave RC4, 0x2000 bytes são os dados criptografados.

O fato de o algoritmo de criptografia RC4 ser usado fica claro na lista a seguir:

Observe que os primeiros 8 bytes por si só não são a chave para o RC4. A chave é o hash SHA1 desses bytes. Você também precisa prestar atenção ao sinalizador 0x280011 para a função CryptDeriveKey. O MSDN tem uma isenção de responsabilidade em relação a este sinalizador:

A partir disso, fica claro que os 16 bits mais altos desse sinalizador definem o tamanho da chave em bits. Ou seja, em bytes, o tamanho da chave é: (0x280011 >> 16) / 8 = 5. Portanto, a chave será os primeiros cinco bytes do hash dos oito primeiros bytes da configuração. Vamos despejar a configuração e escrever um script python que irá descriptografá-lo para nós. O script fica assim:

O resultado de seu trabalho foi o arquivo config.rc4. Abra-o no hiew:

Vemos uma lista descriptografada de áreas administrativas. A primeira palavra é "19nep07" - número da compilação. 16 bytes são alocados para ele. A seguir, é apresentada uma lista de URLs de administrador separados por "|".
Portanto, a primeira chamada para o painel de administração terá este formato:
GUID = 3068075364164635648 & BUILD = 19nep07 & INFO = WIN-56G04BL06SL @ WIN -56G04BL06SL \ Reverse & IP = 35.0.127.52 & TYPE = 1 & WIN = 6.1 (x32

Em seguida, a solicitação gerada é enviada primeiro na lista do painel do administrador.

Em seguida, a resposta do administrador é lida, é claro, se ainda estiver viva. A resposta deve ser codificada em base64. Se não for esse o caso, o próximo administrador da lista será escolhido. Às vezes, os administradores ao vivo retornam uma resposta estranha:

É familiar, não é? Sim, esses são os mesmos
números ! De fato, um autor sabe por que o administrador começa a devolvê-los! Na forma normal, o comando retorna. Infelizmente, é impossível dizer com total certeza qual será o formato da resposta, já que não há tráfego, todos os administradores estão mortos. O arquivo decodificado também é decodificado para 0x7A:

A resposta deve conter um comando. Caso contrário, há um apelo ao próximo painel de administração. O código de comando é codificado como "x:", em que x é a letra que codifica um comando específico. Existem 7 deles: 'r', 'l', 'e', 'b', 'd', 'c', 'n'. Considere os comandos "b" e "r".
Os manipuladores desses comandos têm a mesma função. Nós o nomeamos como GetExe. Aqui está o que parece:

Eu acho que tudo está claro aqui. O trojan faz uma solicitação http e o arquivo executável é retornado em resposta em um formato compactado, que é descompactado. Então variações são possíveis. No caso do comando "b", ocorrem as três ações a seguir:
1. Criação do processo svchost na forma congelada
2. Injeção no espaço de endereço do processo do módulo baixado
3. Controle a transferência para o módulo injetado
No caso do comando r, ocorrem as três ações a seguir:
1. Baixando o arquivo executável chamando a função GetExe.
2. Salvar o arquivo baixado em uma pasta temporária com um nome aleatório.
3. Inicie um arquivo descartado.

Concluído
PS Da próxima vez, podemos analisar o Panda ou algum criptografador. Escreva nos comentários em qual malware você está mais interessado (para fins de pesquisa, é claro).