Utilizar ROP para detectar malware é perda de tempo

Publicado em Serviços e Consultoria, Segurança, por Juniper em 02/11/2016


Todo mês, o engenheiro de software Asher Langton, especialista em malware na equipe do Sky ATP (Advanced Threat Prevention ou prevenção avançada de ameaças) da Juniper Networks, publica um breve estudo sobre algum tipo de malware. Desta vez, Langton decidiu tratar da técnica “return-oriented programming” (ou ROP, cuja definição, em inglês), que é objeto de muita discussão entre especialistas em sandboxes.


Esta discussão acontece porque alguns tipos de malware utilizam ROP para tentar infectar um sistema e, portanto, dizem alguns especialistas, sistemas de detecção de malware precisariam também monitorar este vetor de ataque, mesmo que isto cause excessivo uso de recursos computacionais. Asher contra-argumenta e explica porque o Sky ATP consegue oferecer a mesma proteção sem procurar detectar o ROP propriamente dito. Afinal, diz ele, uma técnica de exploração da segurança de um sistema, como é o caso do ROP, também pode ser detectada por indicadores comportamentais. Este é o post de Langton:


Tradicionalmente, para que uma técnica de exploração (“exploit”) conseguisse infectar um sistema, algumas coisas precisavam acontecer:

 

  1. Encontrar um erro de programação em uma aplicação (por exemplo, Adobe Flash) que permitisse inputs especialmente criados para transbordar ou, de outra maneira, corromper uma região alocada na memória.
  2. Injetar um código executável (shellcode) na memória do programa.
  3. Transferir o controle para este novo código, substituindo informações de controle como um endereço de retorno na pilha de chamadas.


Com esta técnica, a simples abertura de um documento ou mídia resultava na execução arbitrária de um código no sistema visado. O invasor assumia o controle e podia baixar outros tipos de malware, coletar informações do sistema, instalar spyware ou hooks persistentes, etc.


Veja um exemplo simples de um programa vulnerável a um ataque que corrompe a memória.


O ataque aproveita o uso da função insegura gets(), que lê uma string da console “algo digitado por um usuário” e a escreve para uma localização específica na memória sem checar se há suficiente espaço disponível.


Quando a função buggy() é chamada, o computador armazena em memória o endereço de retorno (a próxima instrução em main() depois da chamada de função) no call stack do programa. Depois que buggy() acaba, a execução do programa deveria retornar ao endereço 0x00401047 (visto em reverso aqui na memória do programa porque  a arquitetura x86 é little-Endian).


O nome escrito pelo usuário também é armazenado no stack, nos 8 caracteres alocados para 'str'.


Mas, se o nome tiver mais de 8 caracteres, a função gets() vai despreocupadamente sobrescrever a memória adjacente:


Note que os dois caracteres finais – o ‘n’ final de Langton e o caráter null usado para indicar o final da string – atropelaram metade do endereço de retorno. O resultado é um cash, porque o controle salta para o endereço 0x0040006E. Mas um invasor pode ir mais longe e incluir um código shell executável na string de input e sobrescrever o endereço de retorno original de forma que o controle agora salte para o próprio código do agressor.


Duas técnicas, chamadas de NX (No-eXecute) e DEP (Data Execution Prevention) combatem este tipo de ataque, assegurando, no nível do hardware, que uma determinada seção da memória é gravável ou executável, mas não ambos. Mesmo se o invasor encontrar uma vulnerabilidade de memória e injetar um shellcode, a CPU vai se recusar a executar aquelas instruções.


A técnica ROP supera esta proteção, utilizando o código existente na aplicação de forma errada, ou seja, da forma não pretendida originalmente.


Para entender como isso funciona, vamos começar com uma analogia. Em Wisconsin, há um poder do Executivo conhecido como o veto Frankenstein, que permite a um governante rejeitar seletivamente palavras de determinado projeto de lei. Um exemplo:


 

Ao vetar determinadas palavras e frases, a lei foi modificada de :


[...] o secretário de administração deve transferir para o fundo geral ou para o fundo geral dos saldos desonerados das dotações das agências estatais, tal como definido na subseção (1W) (a), além de adicionar recursos suficientes e dotações de receitas federais, um montante igual a $ 724.900 durante o ano fiscal de 2006-07 [...]


Para:
[...], o secretário de administração deve transferir dos balanços do fundo geral uma quantia igual a $330,000,000 durante o ano fiscal de 2005−06 e 2006-07


Redirecionando seletivamente o texto existente, o governador mudou uma apropriação em quase três ordens de magnitude. (Uma encarnação anterior deste poder de veto permitia aos governadores vetar até letras individuais em um projeto de lei!)

 

De maneira parecida, o ROP reusa trechos existentes de instruções da aplicação vulnerável para fins não originalmente previstos. Ao substituir partes da pilha de chamada, a técnica ROP permite saltar por todo o programa e a cada vez executar seletivamente um pequeno número de instruções anteriores à declaração de uma função 'ret' (daí seu nome).


Como vimos acima, é possível explorar um erro de programação para sobrescrever o endereço de retorno de uma função no stack. Isso nos permite transferir o controle do programa para uma locação arbitrária. Veja o seguinte fragmento de função:


 

Ao estabelecer o endereço de retorno em 0x0040A4BB quando sobrescrevemos o stack, saltamos para o final desta função, ajustando o register eax em 0 ao fazer um  XOR em si mesmo. A instrução de retorno em 0x0040ABD espera encontrar outro endereço de retorno no stack, mas este também pode ser sobrescrito junto com o endereço anterior. Um trecho de código cujo uso é desviado desta maneira se chama dispositivo ROP, e uma exploração conduzida pela técnica ROP é formada por uma cadeia desses dispositivos, chamados em sequência por causa dos erros da memória intencionalmente corrompida. Devido à dificuldade de construir uma sequência adequada de bytes para sobrescrever o stack e controlar o fluxo do programa por meio de uma sequência de fragmentos de funções, esta técnica é usada apenas enquanto é necessária; uma abordagem comum é usar o ROP para ignorar o DEP e depois disso usar técnicas mais tradicionais para concluir a exploração do sistema.


Entendido o mecanismo por trás da técnica ROP, voltamos à questão que iniciou este post: o Sky ATP tenta detectar o ROP diretamente?


A resposta é não, pelas seguintes razões:

 

  1. Detecção de ROP é redundante em um sandbox anti-malware. O ROP é usado como um primeiro passo para rodar um código malicioso em determinado dispositivo. O propósito do malware é fazer algo malicioso: ransomware, uma porta dos fundos para adicionar o computador da vítima a um botnet, roubo de dados etc. A análise dinâmica do motor do Sky ATP detecta um conjunto variado de indicadores de malícia, independentemente de o primeiro ponto de apoio ter vindo de um ROP.
  2. Os ROP são específicos para cada sistema e frágeis, então detectá-los em um sandbox é muito improvável. Como já foi dito, os ROP visam erros de programação e uma aplicação já instalada, então o sandbox também precisa ser configurado com a mesma versão vulnerável. Além disso, como as explorações conduzidas por ROP saltam pelo código executável bruto, pequenas mudanças na configuração do sandbox (diferentes versões de bibliotecas do sistema, variações de hardware etc.) frequentemente tornam o ataque inerte, resultando em – no máximo – um crash da aplicação, não em uma exploração bem sucedida. As pessoas deveriam perguntar a fornecedores de anti-malware vendendo seus detectores de ROP quantas vezes eles realmente detectaram um verdadeiro ROP em ambientes de produção.
  3. Detecção de ROP usa muitos recursos. Para observar padrões ROP no fluxo do programa, seria necessário monitorar as atividades de um sistema no nível do hardware. É muito mais fácil detectar um malware evasivo.


A baixa probabilidade de detectar um ROP em atividade deve ser comparada com o alto custo de emulação no nível de CPU. Multiplique isso pelo número de sistemas em que uma amostra tem que ser executada para assegurar alguma probabilidade de combinação entre a exploração e uma vulnerabilidade e a relação de custo-benefício não tem fundo. Como uma exploração bem-sucedida também seria detectada por indicadores comportamentais, a maior parte das soluções anti-malware – inclusive o Sky ATP – não faz detecção direta de ROP.

 

Leia também
Juniper divulga o primeiro, de uma série de relatórios, sobre as ameaças do momento na rede.
Conheça os malwares que fogem de detecção e análise

 

 


Tags: Sky ATP, Malware, ROP, Detecção, Prevenção, Segurança, Sandboxes

 


Tags: sky-atp, malware, rop, deteccao, prevencao, seguranca, sandboxes


Posts Relacionados


Deixe seu comentário:

=