domingo, 16 de janeiro de 2022

Ofuscação de Código

Introdução


Segundo Basatwar (2022), ofuscação de código se trata da modificação de código executável para que o mesmo não seja de fácil compreensão ou interpretação. A partir da referida técnica de segurança de aplicações, o código-fonte de um dado software se torna ininteligível e impossível para que um terceiro possa compreendê-lo. A ofuscação de código não impacta nem a interface da aplicação nem suas saídas, mas sim na renderização do seu código-fonte, servindo como uma precaução para que o código seja ininteligível quando o mesmo cair em mãos erradas ou não autorizadas.


Ainda de acordo com Basatwar (2022), tal técnica é de suma importância para evitar a chamada Engenharia Reversa. Tornando uma aplicação difícil de ser compreendida a partir de tal técnica, desenvolvedores garantem a propriedade intelectual dos seus produtos contra ameaças de segurança, evitam acesso não autorizado ao código-fonte de aplicações, além de garantir que vulnerabilidades de segurança não sejam descobertas facilmente. Esse processo restringe o acesso malicioso ao código-fonte e, dependendo do tipo de técnica de ofuscação implementada, é possível garantir vários níveis de proteção de código.


Técnicas de Ofuscação de Código


De acordo com Lutkevich (2022?), a ofuscação de código envolve diferentes métodos. Frequentemente, múltiplas técnicas são usadas em conjunto para reforçar a ofuscação. Programas desenvolvidos em algumas linguagens compiladas, como C# e Java, são fáceis de serem ofuscadas, já que tais linguagens criam instruções de nível intermediário que geralmente são fáceis de serem acessadas e compreendidas para ofuscação. Em contraste, linguagens como C++ dificultam a ofuscação de código, visto que compilam diretamente para linguagem de máquina, mais difícil de ser interpretada pelos desenvolvedores inexperientes no uso de linguagens de baixo nível.


Dentre as técnicas existentes, Lutkevich (2022?) lista as seguintes:


  • Renomeação (renaming) - O ofuscador altera os identificadores de métodos e variáveis. Os novos nomes podem incluir caracteres invisíveis ou fora de contexto;

  • Empacotamento (packing) - O código-fonte passa por um processo de compressão, tornando o código ininteligível para o engenheiro reverso que desconhece o processo de descompressão do mesmo;

  • Fluxo de controle (control flow) - O código-fonte descompilado é feito para ser renderizado sob a lógica de espaguete (spaghetti logic), um anti padrão de projeto onde o objetivo é deixar o código intencionalmente desestruturado e “mal escrito”, resultando em um código difícil de interpretar;

  • Transformação no Padrão de Instruções (Instruction Pattern Transformation) - Nesta abordagem, o ofuscador acessa instruções comuns criadas pelo compilador e as torna mais complexas (é o “fazer a mesma coisa de uma maneira diferente, de forma não usual”);

  • Inserção de Código Fictício (Dummy Code Insertion) - Código fictício pode ser incluído ao código-fonte de um programa, sem afetar a lógica do programa nem suas saídas, com o objetivo de confundir ou dificultar a compreensão do código por parte de um engenheiro reverso;

  • Remoção de Metadados ou Comentários (Metadata or Unused Code Removal) - Metadados e comentários dão ao engenheiro reverso informações extra sobre o programa a ser quebrado;

  • Inserção de predicados opacos (Opaque Predicate Insertion) - Um predicado em um código-fonte é uma expressão lógica que retorna uma saída booleana (verdadeiro ou falso). Predicados opacos são estruturas condicionais onde suas saídas não são facilmente determinadas com análise estatística. Inserindo um predicado opaco, é possível introduzir código desnecessário (Dummy Code) que nunca será executado, mas fará com que um engenheiro reverso tente compreender sua lógica em vão;

  • Anti-debug - Programadores utilizam ferramentas de depuração para examinar códigos-fonte linha a linha. Com tais ferramentas, engenheiros de software podem, por exemplo, encontrar e solucionar problemas. Porém, também permitem a hackers realizar engenharia reversa. Desenvolvedores podem adotar ferramentas anti-debug para identificar quando um hacker está executando um programa de depuração em um ataque;

  • Anti-tamper - Essas ferramentas detectam código que foi adulterado. Na ocorrência de adulteração, o programa é automaticamente interrompido;

  • Criptografia de Strings - Este método usa criptografia para ocultar os Strings no executável e restaura apenas os valores que são necessários na execução do programa. Tal técnica dificulta a engenharia reversa baseada na busca de Strings particulares;

  • Transposição de código - Aqui é feita a reordenação de rotinas e condicionais no código-fonte sem ter um efeito visível no seu comportamento. 


Basatwar (2022) ainda inclui as seguintes técnicas de ofuscação:


  • Ofuscação de Agregação (Aggregation Obfuscation) - Tal técnica foca em alterar a forma como os dados são armazenados em um programa. Por exemplo, matrizes podem ser quebradas em vários vetores, que podem ser referenciados em partes diferentes de um mesmo programa;

  • Ofuscação de armazenamento (Storage Obfuscation) - Nessa técnica, é alterada a maneira como os dados são armazenados na memória. Por exemplo, desenvolvedores podem alterar o escopo original de variáveis (local e global), alterando a real natureza do comportamento desta variável;

  • Ofuscação de ordenação (Ordering Obfuscation) - Este método reordena os dados sem alterar o comportamento de um programa. A ordenação original poderá ser alcançada a partir da implementação de um módulo separado, dedicado para tal processo.

  • Ofuscação de Endereçamento de Memória (Address Obfuscation) - A cada execução de programa, seus endereços virtuais de código e dados são randomizados. Tal técnica faz com que as explorações de erro de memória sejam dificultadas.

Influência da Ofuscação de Código no Desempenho de Aplicações


Basatwar (2022) afirma que a ofuscação de código traz mudanças profundas na estrutura de código de um programa. Com isso, tais mudanças podem interferir significativamente na sua performance. Porém ele pondera: tal interferência pode variar, dependendo da técnica de ofuscação adotada. Por exemplo: Em geral, ofuscação baseada em renaming dificilmente irá impactar no desempenho de aplicações, visto que a mesma é baseada apenas na alteração de identificadores de funções, classes, variáveis, entre outros; Já a ofuscação baseada em fluxo de controle gera um impacto negativo em performance: a inclusão de blocos iterativos para tornar o código mais difícil de ser compreendido por um terceiro adiciona um certo overhead à aplicação, devendo ser utilizada com cautela.


Basatwar (2022) ainda quantifica tal influência: O impacto na performance devido a ofuscação normalmente varia entre 10% a 80%. Logo, a escolha de qual(is) técnica(s) deve ser baseada não apenas na ofuscação de código em si, mas no custo mínimo de desempenho para a aplicação.


Além de problemas associados com desempenho, Lutkevich (2022?) também aponta um problema ético em relação ao uso da ofuscação de código: a partir da referida técnica, também é possível ofuscar malwares, prejudicando por exemplo a ação de antivírus em sua detecção. Tornando o código de malwares ofuscados, os mesmos podem parecer aplicações legítimas ou inofensivas aos utilitários. Alguns antivírus inclusive inutilizam aplicações que possuam código ofuscado justamente para “não correrem o risco”.

Estudo de Caso: Construct 2


O Construct 2 é uma poderosa aplicação projetada para a criação de jogos HTML5 2D multiplataforma. É uma excelente ferramenta para iniciantes no mundo da programação de jogos (já que não é necessário conhecimento prévio em Javascript e HTML5) e para desenvolvedores experientes (por se tratar de uma ferramenta RAD - Rapid Application Development) (SCIRRA, 2021?). Dentre as principais funcionalidades desta aplicação, tem-se a criação de jogos online a partir da geração automática de código JavaScript para várias demandas genéricas de games, como física, uso de dispositivos de I/O, animação, eventos, entre outros. Por se tratar de uma linguagem interpretada e classificada como linguagem client-side, um jogador mais curioso poderia ter acesso ao código-fonte JavaScript gerado pelo Construct 2 para o game alvo, tornando tanto os jogos gerados pela ferramenta quanto a própria ferramenta em si bastante vulnerável para ações de Engenharia Reversa. Sabendo disso, os desenvolvedores da aplicação implementaram procedimentos de ofuscação de código em todos os módulos JavaScript gerados para os games desenvolvidos a partir da mesma. 


Na Figura 1, é possível verificar um trecho de código JavaScript gerado para um jogo hipotético criado a partir da plataforma. Fazendo uma análise rápida no código-fonte em questão, é possível constatar a aplicação, no mínimo, das técnicas de renaming e fluxo de controle (o código está praticamente implementado em uma única linha) por parte do Construct 2, dificultando bastante sua análise, até mesmo para quem criou o jogo. 


Figura 1 - Exemplo de código-fonte JavaScript gerado para um módulo de game criado a partir do Construct 2


  

Conclusão


Tópico recorrente em editais de concurso público com foco em Segurança da Informação, a ofuscação de código define um conjunto de métodos e técnicas que objetivam ocultar código-fonte e, assim, prejudicar ações de Engenharia Reversa em aplicações, garantindo a proteção da lógica de programação adotada no desenvolvimento de software. A literatura e estudos de caso demonstram várias ações que podem ser seguidas por desenvolvedores para atingir tal objetivo. Tais técnicas, inclusive, podem ser encadeadas para garantir um maior nível de ofuscação de código. A depender da complexidade da(s) técnica(s) de ofuscação adotada(s), quedas de desempenho podem ocorrer. Assim como a maioria das invenções humanas, técnicas de ofuscação também podem ser utilizadas para o mau: é possível ofuscar código malicioso contido em malwares, confundindo antivírus no processo de detecção dos mesmos.


Exercícios


1) [Ano: 2016, Banca: IADES, Órgão: PC-DF, Prova: IADES - 2016 - PC-DF - Perito Criminal - Ciência da Computação/Informática] - Técnicas de ofuscação de código são úteis para proteger a implementação do código-fonte contra agentes mal-intencionados. Isso é especialmente importante quando, por exemplo, deseja-se dificultar o acesso ao código Javascript que é transmitido para o lado cliente de uma aplicação web ou quando se deseja proteger aplicações executadas por interpretadores chamados máquinas virtuais. Acerca dos conceitos relativos às técnicas de proteção do código fonte, assinale a alternativa correta.


  1. A ofuscação de código baseada em deslocamento de bits pode ser interpretada pelo interpretador ou compilador da linguagem de programação utilizada, sem prejuízo às respectivas funcionalidades.

  2. A criptografia e ofuscação de código é uma técnica aplicada após a compilação do programa, modificando o binário original, com o objetivo de protegê-lo de técnicas de cracking. Assim, apesar de impedir a engenharia reversa com um alto nível de proteção, a técnica tem custo muito elevado e é pouco aplicada.

  3. A técnica de eliminação de informação simbólica é uma técnica de ofuscação de código que remove informação sobre links simbólicos do software, tornando a engenharia reversa mais onerosa.

  4. Realizar a ofuscação do código geralmente tem um custo associado. Isso pode manifestar-se na forma de código maior, tempos de execução mais lentos ou consumo aumentado de memória em tempo de execução.

  5. Técnicas de criptografia de código que utilizam chaves elípticas assimétricas são altamente sofisticadas e realizam uma proteção completa do código das aplicações, mas dependem de trocas de chaves constantes em pontos remotos para que o carregador da aplicação funcione corretamente. É muito utilizada em jogos on-line.


2) [Ano: 2018, Banca: FAURGS, Órgão: BANRISUL, Prova: FAURGS - 2018 - BANRISUL - Segurança da Tecnologia da Informação] - Considere as afirmações abaixo sobre os diferentes tipos de códigos maliciosos.


I - Técnicas como ofuscação e polimorfismo são utilizadas por atacantes para dificultar a análise de um código malicioso. 

II - Um Spyware pode capturar dados bancários inseridos pelo usuário em um sistema comprometido. 

III - Ransomware é um tipo de código malicioso que exige pagamento de resgate para restabelecer o acesso de dados armazenados em um dispositivo. 

IV - Backdoor é um código malicioso que permite o retorno de um atacante a um sistema comprometido. 

V - RootKit é um código malicioso que tem por objetivo ocultar as atividades do invasor no sistema comprometido.


Quais estão corretas?


  1. Apenas III, IV e V.

  2. Apenas I, II, III e IV.

  3. Apenas I, II, IV e V.

  4. Apenas I, III, IV e V.

  5. I, II, III, IV e V.


3) [Instituto AOCP - Perito (ITEP RN)/Criminal/Computação/2021] - Sobre a engenharia reversa de código e suas aplicações, assinale a alternativa correta.


  1. Inclusão de mecanismos antidebug, encriptação e ofuscação de código são exemplos de abordagens contra engenharia reversa.

  2. É uma prática que tem como único objetivo a decompilação de programas para roubo de código fonte.

  3. Sua aplicação mais comum é em programas considerados softwares livres, uma vez que precisam ter seus códigos fontes relevados.

  4. Engenharia reversa é sempre um problema do ponto de vista da segurança da informação.

  5. Linguagens de alto nível orientadas a objeto são imunes a essa prática devido ao polimorfismo.


4) [CRBM - Técnico - Informática (2021)] - A segurança das redes de computadores é realizada por meio de diversas camadas de políticas e controles que são implementadas com o intuito de detectar, mitigar e prevenir ataques e ameaças ao ambiente computacional. Com relação às ameaças às redes de computadores e aos recursos de segurança que podem ser implementados, julgue o item.


Os softwares antivírus, ou antimalwares, trabalham ativamente para impedir que um malware infecte um computador. Entretanto, os malwares modernos utilizam-se de vários métodos para ocultar suas reais intenções, ocultando uma parte do código malicioso para evitar a detecção. Uma das formas por meio das quais um vírus faz isso chama-se ofuscação de código.


  1. Certo

  2. Errado


5 - [FUNIVERSA - 2012 - PC-DF - Perito Criminal - Informática, Disciplina: Engenharia de Software (TI)] - Em muitos casos, é desejável criar softwares com proteção contra reversão de código, ou seja, desenvolver programas que apliquem técnicas antiengenharia-reversa. Assinale a alternativa que apresenta somente exemplos dessas técnicas.


A) Transformações de dados, confusão de registradores, técnicas ativas de antidebugging.

B) Ofuscação de código, eliminação de informação simbólica, uso de árvores transversais.

C) Transformações no controle de fluxo, transformações de dados, ofuscação e encriptação de código.

D) Encriptação de código, bloqueio de acesso à memória, confusão de disassemblers.

E) Varredura linear recursiva, técnicas ativas de antidebugging, transformações no controle de fluxo.


Gabarito


1 - D / 2 - E / 3 - A / 4 - A / 5 - C

Referências


BASATWAR, G.  Code Obfuscation: A Comprehensive Guide Against Reverse-Engineering Attempts. AppSealing Blog. [S.I.] 2022. Disponível em: <https://www.appsealing.com/code-obfuscation/> Acesso em: 12 jan. 2022.


LUTKEVICH, B.  Obfuscation. TechTarget. [S.I.] [2022?]. Disponível em: <https://www.techtarget.com/searchsecurity/definition/obfuscation> Acesso em: 12 jan. 2022.


SCIRRA. Construct 2. [S.I] [2021?]. Disponível em: <https://www.construct.net/en/construct-2/download> Acesso em: 13 jan. 2022.


Nenhum comentário:

Postar um comentário

Técnicas de Recuperação de Arquivos Apagados

Fonte:  MaxP ixel.net Introdução A complexidade na recuperação de um arquivo excluído, seja de forma acidental ou não, depende da forma e, p...