Um guia: engenharia reversa de ofuscação de código
Publicados: 2021-11-17Figuras de ofuscação de código são uma das abordagens de segurança de aplicativos mais populares para impedir a invasão de aplicativos. É um dos esforços de AppSec sugeridos com mais frequência por especialistas em segurança em todo o mundo e geralmente atende aos requisitos mínimos de segurança do seu aplicativo. Essa estratégia é frequentemente usada como um importante mecanismo de defesa contra tentativas de hackers e protege contra ameaças típicas, como injeção de código, engenharia reversa e adulteração de informações pessoais de clientes e usuários de aplicativos.
Ofuscação do código?
A prática de ofuscar executáveis de tal forma que não eram mais compreensíveis, inteligíveis ou práticos é conhecida como ofuscação de código. O código-fonte foi ofuscado na medida em que é incompreensível e difícil para um terceiro entender, quanto mais executar. A interface do usuário final ou a saída pretendida do código não são afetadas pela obscuridade. É apenas uma medida de precaução para tornar o código inútil para qualquer hacker em potencial que tenha acesso ao código executável de um software.
Por que é necessário ofuscar o código?
A ofuscação de código é especialmente importante para software de código aberto, que tem uma desvantagem significativa em termos de hackabilidade para benefício pessoal. Os desenvolvedores garantem que a propriedade intelectual de seus produtos está protegida contra riscos de segurança, acesso ilegal e descoberta de falhas de aplicativos, dificultando a engenharia reversa de um programa.
Independentemente do tipo de técnica de obscurecimento utilizada, essa abordagem restringe o código-fonte perigoso e garante níveis variados de segurança do programa. As razões de tempo, custo e recursos favorecem o abandono de seu código quando ele é ofuscado, pois o código descompilado se torna ilegível.
Técnicas para ofuscação de código
A ofuscação funciona em vários níveis: pode ser implementada no nível da estrutura semântica/léxica do código ou no nível da estrutura de dados/fluxo de controle. As estratégias de ofuscação também diferem dependendo da ação no código. Em essência, a equipe de segurança determina o tipo de ofuscação a ser usado no código em cooperação com a equipe de desenvolvimento.
A ofuscação deve ser renomeada.
Essa abordagem envolve nomear variáveis de forma confusa para que o objetivo real de utilizá-las seja escondido de maneira inteligente. Os descompiladores têm dificuldade em entender o fluxo de controle, pois métodos e variáveis são renomeados com várias notações e números. Esse método de ofuscação é comumente usado para disfarçar o código do aplicativo da plataforma Java, .NET e Android. Isso é classificado como ofuscação de layout, pois visa o código-fonte diretamente para fornecer uma camada de proteção para o aplicativo.
Ofuscação de dados
Esse método foca nas estruturas de dados utilizadas no código, impossibilitando o hacker de acessar o verdadeiro objetivo do programa. Isso pode implicar a alteração da forma como os dados são armazenados na memória pelo software e como esses dados são processados para produzir o resultado final. Este procedimento pode ser feito de várias maneiras:
1. Ofuscação de Agregação
A forma como os dados são salvos no software muda como resultado disso. Arrays, por exemplo, podem ser divididos em vários subarrays que podem ser referenciados em todo o programa.
2. Ofuscação do armazenamento de dados
Isso tem um impacto na forma como os dados são armazenados na memória. Os desenvolvedores podem, por exemplo, alternar entre o armazenamento de variáveis local e global para obscurecer a verdadeira natureza do comportamento da variável.
3. Obtenção de ofuscação sob demanda
Essa abordagem altera a ordem dos dados sem alterar a funcionalidade do trecho de programa/código. Os desenvolvedores conseguem isso criando um módulo distinto que é invocado para cada instância da referência de variável.
4. Criptografia de strings
Essa técnica criptografa todas as strings legíveis, resultando em um código ilegível. Quando o software é executado, eles devem ser descriptografados em tempo de execução.
5. Ofuscação de Controle/Fluxo de Código
A maneira pela qual o controle é transmitido de uma parte da base de código para outra é crucial para estabelecer o objetivo do programa. Ofuscar esse fluxo é frequentemente a maneira mais lucrativa de perverter o fluxo do jogo. Essa estratégia de ofuscação mantém os hackers afastados, dificultando que eles descubram como e por que o código está seguindo um caminho específico.
A inclusão de instruções aleatórias e inesperadas, bem como instruções de alternância de maiúsculas e minúsculas desnecessárias (código morto) que nunca seriam executadas, é uma das maneiras mais comuns de realizar essa estratégia de ofuscação. Essas afirmações não têm outra função, exceto deixar perplexo o hacker visado. No caso de orientação de programa condicional, essa mudança na sequência de instruções de execução do programa é extremamente útil.

A ofuscação está sendo depurada.
As informações de depuração são frequentemente úteis para determinar informações vitais sobre o fluxo e os defeitos do programa descompilando e recompilando o código-fonte. É fundamental ocultar esses dados de identificação alterando suas identidades, números de linha ou desativando totalmente o acesso aos dados de depuração.
A ofuscação deve ser abordada.
Erros de programação de memória se espalharam em ataques, especialmente em linguagens não seguras para memória, como C e C++. As falhas de segurança são frequentemente causadas por erros como acesso descontrolado ao array. A abordagem de ofuscação de endereço dificulta a engenharia reversa, pois os endereços virtuais do código e os dados do programa são randomizados cada vez que o código convertido é executado. Como resultado, a maioria dos ataques de erro de memória não são determinísticos, com uma probabilidade muito baixa de sucesso.
Codificação Personalizada
Os desenvolvedores usam essa abordagem para criptografar strings com um algoritmo personalizado e, em seguida, fornecer uma função de decodificador para recuperar o código original.
Argumentos passados em tempo de execução
É possível modificar o programa de forma que ele espere parâmetros em tempo de execução. Para decodificar as variáveis, o usuário deve ter o código e a chave de descriptografia.
Para desenvolver um método de defesa em camadas para proteger aplicativos contra diversas ameaças à segurança, a equipe de segurança pode optar por implantar mais de uma técnica ao mesmo tempo.
Conclusão
Para resumir, a má orientação por si só é ineficaz no combate a preocupações de segurança avançadas. É mais difícil desofuscar o código devido à disponibilidade de software ai e à habilidade dos hackers, mas não é impossível. Como resultado, a criptografia não é uma panacéia para todas as preocupações de segurança de software.
A equipe de desenvolvimento pode usar várias abordagens de ofuscação de código para proteger seu código em um ambiente não confiável, dependendo da necessidade de segurança, natureza do programa e referência de desempenho. Estes devem ser realizados tendo em conta as vantagens e desvantagens de cada abordagem. Outras iniciativas de AppSec, como criptografia, RASP, regulamentos de retenção de dados e assim por diante, devem ser apoiadas por essa estratégia. Quando combinado com soluções RASP como AppSealing, torna-se um potente antídoto para as preocupações de segurança atuais.